본문 바로가기
데이터분석/Pandas

[Python] Pandas 03 _ pandas_2D_DataFrame

by nemonemonemo 2025. 8. 19.

앞에서 한 1차원 적인 Series --> 2차원으로 확장 DataFrame

pandas의 2차원 자료형 : DataFrame

  • 코드적
    • 2중 for문 기본 형식
    • 벡터연산 : 기능을 중심으로 코드를 간결하게(줄 중심)
    • 내가 만든 인덱스
      • 가로index, 세로columns
      • 태생적인 가로 정수 인덱스
      • 태생적인 세로 정수 인덱스
import pandas as pd
import numpy as np

d = [1,2,3,4,5]
d_series = pd.Series(d)
d_series
#   0
#0	1
#1	2
#2	3
#3	4
#4	5
#
#dtype: int64

d_df = pd.DataFrame(d)
d_df
#   0
#0	1
#1	2
#2	3
#3	4
#4	5

d_df.index
#RangeIndex(start=0, stop=5, step=1)

d_series.index
#RangeIndex(start=0, stop=5, step=1)

d_series.columns #오류
#d_series.columns가 에러 나는 이유는,
#Series에는 .columns 속성이 없기 때문

d_df.columns
#RangeIndex(start=0, stop=1, step=1)


Series는 명확하게 1차원의 자료형 : 단순 몇 번째 → 인덱스

DataFrame은 명확하게 2차원의 자료형 → 가로(index)/세로(columns)

할 일 : 내가 원하는 컬럼으로 이름 변경

  • FM : rename
  • AM: 세로 인덱스(columns)에 접근해서 수정
d_df.columns = ["col1"] #선호하진 않음
d_df
#  col1
#0	1
#1	2
#2	3
#3	4
#4	5

d_df["col1"] #비공식적으로 컬럼에 대한 값을 접근하는 방식
#  col1
#0	1
#1	2
#2	3
#3	4
#4	5
#dtype: int64

type(d_df)
#pandas.core.frame.DataFrame

type(d_df["col1"])
#pandas.core.series.Series

#특히 1줄에 대해서는 2차원 DF // 1차원 Series ==> 이런 부분에 유의해라 


할 일 : 새로운 컬럼을 추가

  • 전제조건 : 기존의 DF이 있다고 가정하고 하는 방식
d
#[1, 2, 3, 4, 5]

d_df["new_col2"] =d # 컬럼이 옆으로 확장 
d_df
#	 col1	new_col2
#0	 1	   1
#1	 2	   2
#2	 3	   3
#3	 4	   4
#4	 5	   5

d_df["new_col3"] =10
d_df
#  col1	new_col2	new_col3
#0	1	    1	10
#1	2	    2	10
#2	3	    3	10
#3	4	4	10
#4	5	5	10

가정

  • 기존 col1의 속성값에 new_col3의 속성값을 더해서 더 좋은 지표/특징/컬럼을 생성하자
  • sql) select (amount*price) from ~~~~~
  • ⇒ (sql에서는 서브쿼리에 담아서 넣어줘야했다면)새로운 컬럼을 바로 DF에 추가하자
d_df["new"] = d_df["col1"] + d_df["new_col3"]
d_df
#  col1	new_col2	new_col3	new
#0	1	     1	       10	     11
#1	2	     2	       10	     12
#2	3	     3	       10	     13
#3	4	     4	       10	     14
#4	5	     5	       10	     15

지우는 것도 가능해야함 ⇒ 상당히 방법이 다양함

#m1) 파이썬 del 지우자 ==>  dict 유사
del d_df["col1"]
d_df
#  new_col2	new_col3	new
#0	  1	       10	     11
#1	  2	       10	     12
#2	  3	       10	     13
#3	  4	       10	     14
#4	  5	       10	     15

#m2) pandas에서 지우는 기능 : drop 메서드
# ==> pandas 기본적인 데이터 핸들링 할 때 필요한 기능으로 만들어 둠
#     여러 시도, 테스트 진행하면서 최종적으로 여러 실험을 하면서 끌고감
# ==> pandas 기본적으로 원본을 변경하는 메서드 -> 바로 적용하지 않음 
#                                                 바로 변경하는 inplace = T/F
#                                                 (재할당없이 동작하도록)
# ==> 가로줄 제거 : axis=0
#     세로줄 제거 : axis=1

d_df.drop("new") #2차원이니까 가로를 지우라는 거야 세로를 지우라는 거야? 오류남 

d_df.drop("new", axis = 1)
#   new_col2	new_col3
#0	   1	       10
#1	   2	       10
#2	   3	       10
#3	   4	       10
#4	   5	       10

d_df # 원본 변경 X
#  new_col2	new_col3	new
#0	  1	       10	     11
#1	  2	       10	     12
#2	  3	       10	     13
#3	  4	       10	     14
#4	  5	       10	     15

d_df.drop("new", axis = 1, inplace=True)
d_df
#   new_col2	new_col3
#0	   1	       10
#1	   2	       10
#2	   3	       10
#3	   4	       10
#4	   5	       10

#가로줄 제거 : 샘플을 제거
#--> 가로줄 인덱스 2번을 지우자 
d_df
#   new_col2	new_col3
#0	   1	       10
#1	   2	       10
#2	   3	       10
#3	   4	       10
#4	   5	       10

d_df.drop(1,axis=1) #내가 만든 거 우선?이라 정수인덱스는 삭제하면서 다 사라지고, 내가 만든 인덱스만 남음 
#KeyError: '[1] not found in axis'

d_df.drop(2,axis=0)
#	  new_col2	new_col3
#0	   1	       10
#1	   2	       10
#3	   4	       10
#4	   5	       10

d_df #원본에서는 사라지지 않음 
#   new_col2	new_col3
#0	   1	       10
#1	   2	       10
#2	   3	       10
#3	   4	       10
#4	   5	       10

d_df.drop(2,axis=0, inplace=True)
d_df
#	  new_col2	new_col3
#0	   1	       10
#1	   2	       10
#3	   4	       10
#4	   5	       10

#참고)
print(d_df.ndim)
print(d_df.shape)
print(d_df.shape[0])
print(len(d_df))
#2
#(4, 2)
#4
#4

#아무 생각없이 가로줄 중심으로 돌리겠다
for i in range(len(d_df)):
    print(i)
    print(d_df.at[i,"new_col2"])
    #왜 오류날까?
    #아까 위에서 중간에 2번째 행 지워서 
    #정수 인덱스순서대로그냥 돌리면 오류나
    #중간에 빠진 애들 있는지 잘 체크
    
 d_df.index
 #Index([0, 1, 3, 4], dtype='int64')
 
 
 for i in d_df.index:
    print(d_df.at[i,"new_col2"])
#1
#2
#4
#5

# --> 중간에 이렇게 정수 인덱스가 꼬일 수 있으니
#     재정리해주는 기능이 있다 -> reset_index()

d_df.reset_index() #정수기반의 인덱스로 초기화
#주의할 점 : 정수 인덱스로만 변환함  ->인덱스가 있었다면 없어지고 정수로만 남음
#  index	new_col2	new_col3
#0	0	        1	      10
#1	1	        2	      10
#2	3	        4	      10
#3	4	        5	      10


2D DataFrame을 샘플을 만들어서 보자

stcok_price_df = pd.DataFrame(
    data = [10000, 10300, 9900, 10500, 11000],
    index = ["2025-08-01", "2025-08-02","2025-08-03",
             "2025-08-04","2025-08-5"]
    # skip: 세로줄에 대한 나의 인덱스 : columns
)
stcok_price_df
#	             0
#2025-08-01	10000
#2025-08-02	10300
#2025-08-03	9900
#2025-08-04	10500
#2025-08-5	11000

  1. 세로 줄에 대한 나만의 인덱스 부여 : 컬럼명 만들자!
    1. FM적인 방법
      1. rename (잘 알아두면 간간히 사용하는 기능)
        1. 뭐를 뭐로 바꿔줘 → 연결 dict
        2. 주의사항 → 에러를 잘 안 던짐 ⇒ 진짜 원하는 변경이 되었는지 꼭 체크해야함
stcok_price_df.rename(columns = {"0":"시가"})
#	             0
#2025-08-01	10000
#2025-08-02	10300
#2025-08-03	9900
#2025-08-04	10500
#2025-08-5	11000
#안 바뀜 but 에러도 안 남
#0이 정수인데 "0" 문자로 써서 안 바뀜

stcok_price_df.rename(columns = {0:"시가"})
#	           시가
#2025-08-01	10000
#2025-08-02	10300
#2025-08-03	9900
#2025-08-04	10500
#2025-08-5	11000

stcok_price_df #원본 안 바뀜
#	             0
#2025-08-01	10000
#2025-08-02	10300
#2025-08-03	9900
#2025-08-04	10500
#2025-08-5	11000

stcok_price_df.rename( columns = {0:"시가"}, inplace=True)
stcok_price_df
#	           시가
#2025-08-01	10000
#2025-08-02	10300
#2025-08-03	9900
#2025-08-04	10500
#2025-08-5	11000

stcok_price_df.rename(index = {"2025-08-5":"2025-08-05"})
#	           시가
#2025-08-01	10000
#2025-08-02	10300
#2025-08-03	9900
#2025-08-04	10500
#2025-08-05	11000

#rename => 내가 만든 가로(index), 세로(columns)에 대한 익덱스 변경

stcok_price_df
#	           시가
#2025-08-01	10000
#2025-08-02	10300
#2025-08-03	9900
#2025-08-04	10500
#2025-08-5	11000

stcok_price_df["종가"] = [11000,12000,10000,13000,12000]
stcok_price_df["고가"] = [13000,15000,15000,19000,17000]
stcok_price_df["저가"] = [3200,5800,5050,8500,7000]
stcok_price_df
#           시가	종가	고가	저가
#2025-08-01	10000	11000	13000	3200
#2025-08-02	10300	12000	15000	5800
#2025-08-03	9900	10000	15000	5050
#2025-08-04	10500	13000	19000	8500
#2025-08-5	11000	12000	17000	7000

2D 상에서 값에 대한 FM적인 접근을 해보자

  • 1개 값을 접근(at/iat) vs 여러개 값 접근 (loc/iloc)
  • 2차원이기 때문에 : 인덱스 가로/세로 → 2개 필요 (가로/세로 기준을 통일! 정수, 내가 만든 것 )
stcok_price_df.iat[0,0]
#np.int64(10000)

stcok_price_df.iat[0,1]
#np.int64(11000)

stcok_price_df.at["2025-08-02","종가"]
#np.int64(12000)

#2025년 8월 3일 시가하고, 고가는 얼마?
stcok_price_df.loc["2025-08-03",["시가","고가"]]
#	    2025-08-03
#시가	   9900
#고가	  15000
#
#dtype: int64

type(stcok_price_df.loc[ "2025-08-03", ["시가","고가"] ])
#pandas.core.series.Series

stcok_price_df.loc[ "2025-08-03":"2025-08-04", ["시가","고가"] ]
#	           시가	고가
#2025-08-03	9900	15000
#2025-08-04	10500	19000

type(stcok_price_df.loc[ "2025-08-03":"2025-08-04", ["시가","고가"] ])
#pandas.core.frame.DataFrame

stcok_price_df
#            시가	종가	고가	저가
#2025-08-01	10000	11000	13000	3200
#2025-08-02	10300	12000	15000	5800
#2025-08-03	9900	10000	15000	5050
#2025-08-04	10500	13000	19000	8500
#2025-08-5	11000	12000	17000	7000

# 2025년 8월 3일, 시가, 고가에 대해서 정수인덱스로 접근하려면!!!
stcok_price_df.iloc[2,[0,2]]
#	   2025-08-03
#시가	  9900
#고가	  15000
#
#dtype: int64

# 불편한 점 : 많으면,,,언제 찾아요;;;;
# ==> 원하는 컬럼/index 어디에 있는지 정수기반의 위치 정보 찾아주는 메서드
#     get_loc()

# 시가 --> 위치!!!!
#      --> 세로
stcok_price_df.columns.get_loc("시가")
#0

stcok_price_df.columns.get_loc("고가")
#2

# 2025-08-03 위치 --> 가로에서 찾아야함
stcok_price_df.index.get_loc("2025-08-03")
#2

idx = stcok_price_df.index.get_loc("2025-08-03")
cols = [stcok_price_df.columns.get_loc("시가"), stcok_price_df.columns.get_loc("고가")]
stcok_price_df.iloc[idx, cols] # .iloc[2, [0,2]]
#	    2025-08-03
#시가	   9900
#고가	  15000
#
#dtype: int64

idx = stcok_price_df.index.get_loc("2025-08-03")
cols = ["시가","고가", "종가"]
cols_idx = [stcok_price_df.columns.get_loc(c) for c in cols ]
stcok_price_df.iloc[idx, cols_idx] # .iloc[2, [0,2]]
#	2025-08-03
#시가	9900
#고가	15000
#종가	10000
#
#dtype: int64

target_dates = ["2025-08-03"] #*****
idx = [stcok_price_df.index.get_loc(c) for c in target_dates]

cols = ["시가","고가","종가"] #****
cols_idx = [stcok_price_df.columns.get_loc(c) for c in cols]

stcok_price_df.iloc[idx, cols_idx] # .iloc[2, [0,2]]
#	          시가	고가	종가
#2025-08-03	9900	15000	10000
###########얘는 왜 위랑 행렬 바껴서 나오는거지....???????
  • 왜 위랑 행렬 바껴서 나오는거지....???????
    idx = stcok_price_df.index.get_loc("2025-08-03")  # -> 예: 2
    cols_idx = [stcok_price_df.columns.get_loc(c) for c in cols]  # -> [0,1,2]
    
    stcok_price_df.iloc[idx, cols_idx]
    
    
    • iloc[2, [0,1,2]] → Series 반환
    • 행 인덱스가 단일 값(int)이면 → 해당 행의 한 줄(row)을 Series로 반환
    • Series라서 index(=컬럼 이름)가 세로축, 값이 가로로 출력돼서처럼 보이는 거예요.
    • 시가 9900 고가 15000 종가 10000 Name: 2025-08-03, dtype: int64

    2. 리스트 인덱스 사용 ([int])
    • iloc[[2], [0,1,2]] → DataFrame 반환
    • 행 인덱스가 리스트(list/array)이면 → **DataFrame (2차원)**이 유지됨
    • 따라서 표 형태로처럼 행+열 구조로 출력돼요.
    • 시가 고가 종가 2025-08-03 9900 15000 10000

    핵심 차이
    • 정수 인덱스Series (1D)
    • 리스트 인덱스DataFrame (2D)
  • idx = [stcok_price_df.index.get_loc("2025-08-03")] # -> [2] cols_idx = [stcok_price_df.columns.get_loc(c) for c in cols] # -> [0,1,2] stcok_price_df.iloc[idx, cols_idx]
  • 1. 단일 인덱스 사용 (int)
# 2025월 8월 2일부터 5일까지, 시가,종가, 고가 , 저가 다 보여주세요!!!

stcok_price_df.loc["2025-08-02":"2025-08-5" ,"시가":"저가" ]
#	          시가	종가	고가	저가
#2025-08-02	10300	12000	15000	5800
#2025-08-03	9900	10000	15000	5050
#2025-08-04	10500	13000	19000	8500
#2025-08-5	11000	12000	17000	7000

stcok_price_df.loc["2025-08-02":"2025-08-5" ,:]
#	           저가	고가	종가	시가
#2025-08-02	5800	15000	12000	10300
#2025-08-03	5050	15000	10000	9900
#2025-08-04	8500	19000	13000	10500
#2025-08-5	7000	17000	12000	11000

#참고)
stcok_price_df.loc[:,"시가"] # FM
#	           시가
#2025-08-01	10000
#2025-08-02	10300
#2025-08-03	9900
#2025-08-04	10500
#2025-08-5	11000
#
#dtype: int64

stcok_price_df["시가"] # AM --> 간단히 볼 떄는 괜춘!!
# 여러번 하면,,,속도 이슈가 있는 접근 방식임!!!!
#	           시가
#2025-08-01	10000
#2025-08-02	10300
#2025-08-03	9900
#2025-08-04	10500
#2025-08-5	11000
#
#dtype: int64

stcok_price_df.T
#	    2025-08-01	2025-08-02	2025-08-03	2025-08-04	2025-08-5
#시가	 10000	      10300	       9900	      10500	      11000
#종가	 11000	      12000	      10000	      13000	      12000
#고가	 13000	      15000	      15000	      19000	      17000
#저가	 3200	         5800	       5050	       8500	       7000

#참고) pandas에서 기본적으로 가로줄은 index라함
# -->  유사한 기능들이 있음
# --> 가로줄에 대한 인덱스를 수정 :df.rename(index = {~~:~~})
# --> 가로줄에 대한 인덱스 초기화(정수) : df.reset_index()
# --> 가로줄웨 대한 인덱스를 내가 원하는 (대상)것으로 세팅 : df.reindex()
# +++ 원본을 변경하려면 => inplace = True

stcok_price_df.rename( index={"2025-08-5":"2025-08-05"})
#	          시가	종가	고가	저가
#2025-08-01	10000	11000	13000	3200
#2025-08-02	10300	12000	15000	5800
#2025-08-03	9900	10000	15000	5050
#2025-08-04	10500	13000	19000	8500
#2025-08-05	11000	12000	17000	7000

stcok_price_df.reset_index()
#	    index	     시가	종가	고가	저가
#0	2025-08-01	10000	11000	13000	3200
#1	2025-08-02	10300	12000	15000	5800
#2	2025-08-03	9900	10000	15000	5050
#3	2025-08-04	10500	13000	19000	8500
#4	2025-08-5	  11000	12000	17000	7000

stcok_price_df
#	          시가	종가	고가	저가
#2025-08-01	10000	11000	13000	3200
#2025-08-02	10300	12000	15000	5800
#2025-08-03	9900	10000	15000	5050
#2025-08-04	10500	13000	19000	8500
#2025-08-5	11000	12000	17000	7000

stcok_price_df.reindex( [ "2025-08-03", "2025-08-5", "2025-08-01"])
#	          시가	종가	고가	저가
#2025-08-03	9900	10000	15000	5050
#2025-08-5	11000	12000	17000	7000
#2025-08-01	10000	11000	13000	3200

stcok_price_df.reindex( [ "2025-08-03", "2025-08-5","2025-08-19"])
#	           시가     종가	   고가	   저가
#2025-08-03	9900.0	10000.0	15000.0	5050.0
#2025-08-5	11000.0	12000.0	17000.0	7000.0
#2025-08-19	  NaN	    NaN	   NaN	   NaN

stcok_price_df
#	          시가	종가	고가	저가
#2025-08-01	10000	11000	13000	3200
#2025-08-02	10300	12000	15000	5800
#2025-08-03	9900	10000	15000	5050
#2025-08-04	10500	13000	19000	8500
#2025-08-5	11000	12000	17000	7000

정렬 ) 이미 만들어져있음

  • 정렬에 대한 기준 → 가로줄/세로줄 기준 선택
    • 가로줄 기준 → index 이름을 중심으로 정렬 세로줄 기준 → index(columns) 이름을 중심으로 정렬
      • df.sort_index(axis=0/1) : 틀 중심으로 정렬
    • 내부 값 자체로 정렬
      • df.sort_values()
  • 컬럼명 중심으로 DF를 정렬해서 보자
    • —> sort_index & 세로줄 columns axis =1
    • 오름/내림 : ascending = T/F (기본: 오름)
stcok_price_df.sort_index( axis=1)
# 	         고가	시가	저가	종가
#2025-08-01	13000	10000	3200	11000
#2025-08-02	15000	10300	5800	12000
#2025-08-03	15000	9900	5050	10000
#2025-08-04	19000	10500	8500	13000
#2025-08-5	17000	11000	7000	12000

stcok_price_df.sort_index( axis=1 , ascending=False)
#	           종가	저가	시가	고가
#2025-08-01	11000	3200	10000	13000
#2025-08-02	12000	5800	10300	15000
#2025-08-03	10000	5050	9900	15000
#2025-08-04	13000	8500	10500	19000
#2025-08-5	12000	7000	11000	17000

#최근 날짜 데이터를 중심으로 탐색을 하자
# --> 오래된 날짜 ; 뒤로, 최신 날짜 : 앞으로 순서를 바꾸자
stcok_price_df.sort_index( axis=0 , ascending=False)
#	          시가	종가	고가	저가
#2025-08-5	11000	12000	17000	7000
#2025-08-04	10500	13000	19000	8500
#2025-08-03	9900	10000	15000	5050
#2025-08-02	10300	12000	15000	5800
#2025-08-01	10000	11000	13000	3200

#df 내부의 값을 중심으로 정렬해서 볼 때도 있음
# ==> 내부의 어떤 줄에 있는 값을 기준으로 할지 지정해야함

stcok_price_df.sort_values(by = "고가")
#	          시가	종가	고가	저가
#2025-08-01	10000	11000	13000	3200
#2025-08-02	10300	12000	15000	5800
#2025-08-03	9900	10000	15000	5050
#2025-08-5	11000	12000	17000	7000
#2025-08-04	10500	13000	19000	8500

stcok_price_df.sort_values(by = "고가", ascending = False)
#	           시가	종가	고가	저가
#2025-08-04	10500	13000	19000	8500
#2025-08-5	11000	12000	17000	7000
#2025-08-03	9900	10000	15000	5050
#2025-08-02	10300	12000	15000	5800
#2025-08-01	10000	11000	13000	3200

stcok_price_df.sort_values(by = ["고가","시가"], ascending = False)
#	           시가	종가	고가	저가
#2025-08-04	10500	13000	19000	8500
#2025-08-5	11000	12000	17000	7000
#2025-08-02	10300	12000	15000	5800
#2025-08-03	9900	10000	15000	5050
#2025-08-01	10000	11000	13000	3200

# ==> sql에서 order by 고가, 시가 와 비슷한 기능임 

참고) rank 등수 선정 : 자세한 방식들은 메뉴얼 참조할 것 ⇒ sql : row_number, rank, dense_rank etc

stcok_price_df["종가"]
#	           종가
#2025-08-01	11000
#2025-08-02	12000
#2025-08-03	10000
#2025-08-04	13000
#2025-08-5	12000
#
#dtype: int64

stcok_price_df["종가"].rank()
#	          종가
#2025-08-01	2.0
#2025-08-02	3.5
#2025-08-03	1.0
#2025-08-04	5.0
#2025-08-5	3.5
#
#dtype: float64

줄단위 연산을 통해서 전처리 /가공

  • 목적
    • 줄단위로 값들을 변경을 하거나 처리해야할 때 편하게 사용
    • 줄 단위로 하고자 하는 일에 대한 규칙
  • sort/sorted( x, key = lambda x : ~~)
  • apply + lambda : 줄 단위로 무엇을 할지 기술 (개별 데이터는 신경쓰지 않고도, 모든 개별 데이터에 적용이 가능함)
  • 코드의 가독성/작성이 요이함 (다른 통계 패키지 차용 R/ SAS etc) <효율성 보장하는 방식은 아님, 속도 빠르지 XXXX>
stcok_price_df
#	          시가	종가	고가	저가
#2025-08-01	10000	11000	13000	3200
#2025-08-02	10300	12000	15000	5800
#2025-08-03	9900	10000	15000	5050
#2025-08-04	10500	13000	19000	8500
#2025-08-5	11000	12000	17000	7000

# ex) 날짜별로 최고가의 가격만 보고 싶다!!!!!
#     (고가 컬럼 이외에 최고가 있다고 가정)
# ==> 체크 : 일단 하려는 일이 줄 단위로 동일한지 : OK
#     기능 : 임의의 가로줄에서,,,여러개 값 중에서 최고값을 선택!!!!
# apply(줄 단위로 롤링해주는 역할) + lambda ( 할 일에 대한 기술 )

stcok_price_df.apply( lambda x: x.max(), axis=1)
#	            0
#2025-08-01	13000
#2025-08-02	15000
#2025-08-03	15000
#2025-08-04	19000
#2025-08-5	17000
#
#dtype: int64

# 날짜별로 최고값과 최저값의 차이를 계산해보고 싶다 ( 그날의 변동성 )
# --> 체크 : 일단 하는 일 -> 줄 단위로 규칙이 있는가
#     기능 : 그 줄의 최고값 - 그 줄의 최저값

stcok_price_df.apply( lambda x: x.max() - x.min(),  axis= 1)
#	            0
#2025-08-01	9800
#2025-08-02	9200
#2025-08-03	9950
#2025-08-04	10500
#2025-08-5	10000
#
#dtype: int64

#기존의 컬럼의 값을 바탕으로 새로운 값/특징/변수 생성해서 컬럼에 추가
# => 그 중에서 그날의 변동성이 중요한 지표인 것 같아서 한 번 해보려고 합니다.
stcok_price_df["Gap"] = stcok_price_df.apply(lambda x : x.max() - x.min(), axis = 1)
stcok_price_df
#            시가	종가	고가	저가	Gap
#2025-08-01	10000	11000	13000	3200	9800
#2025-08-02	10300	12000	15000	5800	9200
#2025-08-03	9900	10000	15000	5050	9950
#2025-08-04	10500	13000	19000	8500	10500
#2025-08-5	11000	12000	17000	7000	10000

# ++ To Do)
# 위의 lambda + apply를 사용하지 말고
# ==> 배치처리를 순회하면서.. 직접 for문으로 작성해보세요
#     + FM적으로 값에 대한 접근을 활용해보면서

stcok_price_df["GapFor"] = 0
stcok_price_df
#	           시가	종가	고가	저가	Gap	 GapFor
#2025-08-01	10000	11000	13000	3200	9800	0
#2025-08-02	10300	12000	15000	5800	9200	0
#2025-08-03	9900	10000	15000	5050	9950	0
#2025-08-04	10500	13000	19000	8500	10500	0
#2025-08-5	11000	12000	17000	7000	10000	0

# --> DF에서 가로줄을 돌아가면서 for문
#            i번쨰 날짜에서 할 일을 생각
#             -> 4개의 가격을 수집(loc, iloc)
#             -> 그 값들에서 Max, min, 차이 계산(max, min)
#             -> 그 날짜의 GapFor 컬럼의 위치에 값을 기록
#               [i번째 가로줄, GapFor] (at/iat)
# cf) 값에 대한 접근 : 정수로 통일하던지, 내가 만든 것들로 통일하던지

# 1) 태생적인 정수인덱스로
for i in range(len(stcok_price_df)):
    print(i)
#0
#1
#2
#3
#4

# 2) 내가 만든 인덱스 중심!!
for i in stcok_price_df.index:
    print(i)
#2025-08-01
#2025-08-02
#2025-08-03
#2025-08-04
#2025-08-5

# sol1)
for i in range(len(stcok_price_df)):
    #i번째 가로줄에서 무엇을 할지
    #1) i번째 가로줄에서 필요한 4개 값 가져오기-> iloc
    data = stcok_price_df.iloc[i,:4] # => 중간에 컬럼이 이상한 거 추가되면 오류
    # 2) max - min
    temp = data.max() - data.min()
    # 3) i번째 가로줄, 세로줄 GapFor(정수인덱스5)
    stcok_price_df.iat[i,5] = temp
print("Done!")
##하드코딩

stcok_price_df
#	          시가	종가	고가	저가	Gap	 GapFor
#2025-08-01	10000	11000	13000	3200	9800	9800
#2025-08-02	10300	12000	15000	5800	9200	9200
#2025-08-03	9900	10000	15000	5050	9950	9950
#2025-08-04	10500	13000	19000	8500	10500	10500
#2025-08-5	11000	12000	17000	7000	10000	10000

# sol1) 수정
# 데이터를 수집할 항목들에 대한 정의....
cols = ["시가","종가","고가","저가"] #List UP
cols_idx = [stcok_price_df.columns.get_loc(c) for c in cols]

# 기록할 컬럼의 위치
new_col_name = "GapFor"#***
stcok_price_df[new_col_name] = 0
gap_idx = stcok_price_df.columns.get_loc(new_col_name)

for i in range(len(stcok_price_df)):
    #i번째 가로줄에서 무엇을 할지
    #1) i번째 가로줄에서 필요한 4개 값 가져오기-> iloc
    data = stcok_price_df.iloc[i, cols_idx] # => 중간에 컬럼이 이상한 거 추가되면 오류
    # 2) max - min
    temp = data.max() - data.min()
    # 3) i번째 가로줄, 세로줄 GapFor(정수인덱스5)
    stcok_price_df.iat[i,gap_idx] = temp
print("Done!")

stcok_price_df
#	           시가	종가	고가	저가	Gap	 GapFor
#2025-08-01	10000	11000	13000	3200	9800	9800
#2025-08-02	10300	12000	15000	5800	9200	9200
#2025-08-03	9900	10000	15000	5050	9950	9950
#2025-08-04	10500	13000	19000	8500	10500	10500
#2025-08-5	11000	12000	17000	7000	10000	10000

# sol2) 내가 만든 인덱스 중심...

cols = ["시가","종가","고가","저가"] #List UP
new_col_name = "GapFor"#***
stcok_price_df[new_col_name] = 0

for i in stcok_price_df.index:
    #내가 만든 것들로 다 접근
    data = stcok_price_df.loc[i, cols]
    temp = data.max()-data.min()
    stcok_price_df.at[ i, new_col_name] = temp
stcok_price_df
#	           시가	종가	고가	저가	Gap	 GapFor
#2025-08-01	10000	11000	13000	3200	9800	9800
#2025-08-02	10300	12000	15000	5800	9200	9200
#2025-08-03	9900	10000	15000	5050	9950	9950
#2025-08-04	10500	13000	19000	8500	10500	10500
#2025-08-5	11000	12000	17000	7000	10000	10000

for i, v in enumerate(stcok_price_df.index):
    print(i,v)
#0 2025-08-01
#1 2025-08-02
#2 2025-08-03
#3 2025-08-04
#4 2025-08-5

stcok_price_df
#	            시가	종가	고가	저가 Gap	GapFor
#2025-08-01	10000	11000	13000	3200	9800	9800
#2025-08-02	10300	12000	15000	5800	9200	9200
#2025-08-03	9900	10000	15000	5050	9950	9950
#2025-08-04	10500	13000	19000	8500	10500	10500
#2025-08-5	11000	12000	17000	7000	10000	10000

# 위의 DF을 날짜별로 시/종/고/저의 평균을 계산해주세요!!!
#  ==> apply+lambda
# +++ 코드에러가 아니라,,값이 진짜 평균 계산값이 맞는지 체크!!!
# sql : avg, python : mean

stcok_price_df.apply( lambda x: x.mean(), axis=1)
#	               0
#2025-08-01	9466.666667
#2025-08-02	10250.000000
#2025-08-03	9975.000000
#2025-08-04	12000.000000
#2025-08-5	11166.666667
#
#dtype: float64

(10000+11000+13000+3200)/4
#9300.0
# 값이 틀림 왜? -> 위는 gap, gapfor까지 포함하여 계산한 값임

stcok_price_df.iloc[:, :4].apply(lambda x: x.mean(), axis=1)
#	            0
#2025-08-01	9300.0
#2025-08-02	10775.0
#2025-08-03	9987.5
#2025-08-04	12750.0
#2025-08-5	11750.0
#
#dtype: float64

stcok_price_df.iloc[:3, :4].apply(lambda x: x.mean(), axis=1)
#	0
#2025-08-01	9300.0
#2025-08-02	10775.0
#2025-08-03	9987.5
#
#dtype: float64

#위를 보면서
#체크!!!)
# DF에서 apply로 적용할 때: 전체에 적용할지 or 일부분에 적용할지 구분하자

# 기타
stcok_price_df.describe()
#	         시가	      종가	         고가	        저가	     Gap	       GapFor
#count	5.000000	   5.000000	     5.00000	    5.000000	   5.000000	    5.000000
#mean	 10340.000000	 11600.000000	 15800.00000	5910.000000	 9890.000000	9890.000000
#std	 439.317653	   1140.175425	 2280.35085	  1999.499937	 466.904701	  466.904701
#min	 9900.000000	 10000.000000	 13000.00000	3200.000000	 9200.000000	9200.000000
#25%	 10000.000000	 11000.000000	 15000.00000	5050.000000	 9800.000000	9800.000000
#50%	 10300.000000	 12000.000000	 15000.00000	5800.000000	 9950.000000	9950.000000
#75%	 10500.000000	 12000.000000	 17000.00000	7000.000000	 10000.000000	10000.000000
#max	 11000.000000	 13000.000000	 19000.00000	8500.000000	 10500.000000	10500.000000

stcok_price_df.info()
#<class 'pandas.core.frame.DataFrame'>
#Index: 5 entries, 2025-08-01 to 2025-08-5
#Data columns (total 6 columns):
# #   Column  Non-Null Count  Dtype
#---  ------  --------------  -----
 #0   시가      5 non-null      int64
 #1   종가      5 non-null      int64
 #2   고가      5 non-null      int64
 #3   저가      5 non-null      int64
 #4   Gap     5 non-null      int64
 #5   GapFor  5 non-null      int64
#dtypes: int64(6)
#memory usage: 452.0+ bytes

stcok_price_df.corr()
# --> 종속성에 대한 체크를 할 떄 사용이 됨!!!
# but) 전통적인 통계 모형 : 종속성이 있는 변수( 키 ~ 몸무게)
#                           계수가 겁나 작거나, 겁나 크거나..
#                           행렬에 대한 이해(독립/종속)-->det ~~~~
#      Tree기반의 모형들은 : 약간의 알빠노!!!!
#                          : 원하는 Cost를 보고,계산을 하는 것임!!!
#                          : 아주~~~심각하게 돌릴 필용까지는 잘 없음..
#                          : 알아서 떨어져 나감;;;
#                          : 통합지표///하나만 선택,,,비교 모델 성능기준..

#	        시가	     종가	    고가	     저가	    Gap	     GapFor
#시가	  1.000000	0.688761	0.658815	0.693863	0.246198	0.246198
#종가	  0.688761	1.000000	0.730769	0.769811	0.272376	0.272376
#고가	  0.658815	0.730769	1.000000	0.984744	0.666850	0.666850
#저가  	0.693863	0.769811	0.984744	1.000000	0.527006	0.527006
#Gap	  0.246198	0.272376	0.666850	0.527006	1.000000	1.000000
#GapFor	0.246198	0.272376	0.666850	0.527006	1.000000	1.000000

'데이터분석 > Pandas' 카테고리의 다른 글

[Python] Pandas 06 _ kobis_api_xml  (0) 2025.08.20
[Python] pandas 05_kobis_api_json  (0) 2025.08.19
[Python] Pandas 04 _ json  (0) 2025.08.19
[Python] Pandas 02 _pandas_1D_Series (2)  (0) 2025.08.19
[Python] Pandas 02 _pandas_1D_Series (1)  (4) 2025.08.18