본문 바로가기
DataFrame

데이터 샘플링

by 자동매매 2022. 4. 9.

출처 : 금융 데이터 분석을 위한 파이썬 판다스

 

 

금융 데이터 분석을 위한 파이썬 판다스

최근 인공지능 AI(Artificial Intelligence)이 보급화되면서 방대한 양의 데이터를 처리하는 방식이 중요해지기 시작했습니다. 판다스(Pandas)는 오픈 소 ...

wikidocs.net

 

import pandas as pd

df = pd.read_excel("DB/ss_ex_1.xlsx", index_col=0)
df.index = pd.to_datetime(df.index)
df = df.sort_index()[['시가', '저가', '고가', '종가', '거래량']]
print(df.head())

                 시가       저가       고가       종가         거래량
일자                                                        
2021-02-15  83800.0  83300.0  84500.0  84200.0  23529706.0
2021-02-16  84500.0  84200.0  86000.0  84900.0  20483100.0
2021-02-17  83900.0  83000.0  84200.0  83200.0  18307735.0
2021-02-18  83200.0  82100.0  83600.0  82100.0  21327683.0
2021-02-19  82300.0  81000.0  82800.0  82600.0  25880879.0

 

resample 메서드

result = df.resample(기준).agg(how)

아래 기준으로 데이터를 샘플링

월(M)/주(W) => 마지막 날짜를 대표값으로 표시  / ( +S) : 첫째 날짜를 대표값으로 표시

일(D)/시(H)/분(T)/초(S)  => 첫째 날짜를 대표값으로 표시

 

# 월단위 그룹핑 후 첫째일 데이터
# 그룹핑 인덱스 -> 그룹의 마지막 인덱스 표시
result = df.resample('M').first()
print(result)

                 시가       저가       고가       종가         거래량
일자                                                        
2021-02-28  83800.0  83300.0  84500.0  84200.0  23529706.0
2021-03-31  85100.0  83000.0  85300.0  83600.0  33498180.0
2021-04-30  82500.0  82000.0  83000.0  82900.0  18676461.0
2021-05-31  81000.0  81000.0  82400.0  81700.0  15710336.0
2021-06-30  80500.0  80100.0  81300.0  80600.0  14058401.0
2021-07-31  80500.0  80000.0  80600.0  80100.0  13382882.0
2021-08-31  79200.0  78700.0  79500.0  79300.0  11739124.0

# 월단위 그룹핑 후 첫째일 데이터
# 그룹핑 인덱스 -> 그룹의 처음 인덱스 표시
result = df.resample('MS').first()
print(result)

                 시가       저가       고가       종가         거래량
일자                                                        
2021-02-01  83800.0  83300.0  84500.0  84200.0  23529706.0
2021-03-01  85100.0  83000.0  85300.0  83600.0  33498180.0
2021-04-01  82500.0  82000.0  83000.0  82900.0  18676461.0
2021-05-01  81000.0  81000.0  82400.0  81700.0  15710336.0
2021-06-01  80500.0  80100.0  81300.0  80600.0  14058401.0
2021-07-01  80500.0  80000.0  80600.0  80100.0  13382882.0
2021-08-01  79200.0  78700.0  79500.0  79300.0  11739124.0

how = {
   "시가": "first",
   "종가": "last",
   "고가": max,
   "저가": min,
   "거래량": sum,
}
result = df.resample('MS').agg(how)
print(result)

                 시가       종가       고가       저가          거래량
일자                                                         
2021-02-01  83800.0  82500.0  86000.0  81000.0  255020740.0
2021-03-01  85100.0  81400.0  85300.0  80600.0  387612356.0
2021-04-01  82500.0  81500.0  86200.0  81500.0  372938171.0
2021-05-01  81000.0  80500.0  83500.0  78400.0  352211074.0
2021-06-01  80500.0  80700.0  83000.0  79600.0  333099465.0
2021-07-01  80500.0  78500.0  81300.0  78100.0  275886253.0
2021-08-01  79200.0  74400.0  83300.0  74100.0  263311167.0

# 3일 단위 그룹핑
result = df.resample('3D').agg(how)
print(result)

                 시가       종가       고가       저가         거래량
일자                                                        
2021-02-15  83800.0  83200.0  86000.0  83000.0  62320541.0
2021-02-18  83200.0  82600.0  83600.0  81000.0  47208562.0
2021-02-21  83800.0  82000.0  84200.0  81100.0  46007200.0
2021-02-24  81800.0  82500.0  85400.0  81300.0  99484437.0
2021-02-27      NaN      NaN      NaN      NaN         0.0

result = df.resample('12H').agg(how)
print(result.head())

                          시가       종가       고가       저가         거래량
일자                                                                 
2021-02-15 00:00:00  83800.0  84200.0  84500.0  83300.0  23529706.0
2021-02-15 12:00:00      NaN      NaN      NaN      NaN         0.0
2021-02-16 00:00:00  84500.0  84900.0  86000.0  84200.0  20483100.0
2021-02-16 12:00:00      NaN      NaN      NaN      NaN         0.0
2021-02-17 00:00:00  83900.0  83200.0  84200.0  83000.0  18307735.0

# ffill(forward fill) 메서드는 결측값을 이전 로우의 값으로 대체
# bfill(backward fill)
df.resample('12H').agg(how).ffill()

                          시가       종가       고가       저가         거래량
일자                                                                 
2021-02-15 00:00:00  83800.0  84200.0  84500.0  83300.0  23529706.0
2021-02-15 12:00:00      NaN      NaN      NaN      NaN         0.0
2021-02-16 00:00:00  84500.0  84900.0  86000.0  84200.0  20483100.0
2021-02-16 12:00:00      NaN      NaN      NaN      NaN         0.0
2021-02-17 00:00:00  83900.0  83200.0  84200.0  83000.0  18307735.0

# 로우에 하나라도 결측값이 있을 경우 NaN으로 거래량을 설정하는 전처리
import numpy as np

temp = df.resample('12H').agg(how)
# isna() : na 존재시 True, any() : 존재하면 True, axis=1 : 로우 단위로 비교교
cond = temp.isna().any(axis=1)  
temp.loc[cond, '거래량'] = np.NaN
result = temp.ffill()
print(result)

                          시가       종가       고가       저가         거래량
일자                                                                 
2021-02-15 00:00:00  83800.0  84200.0  84500.0  83300.0  23529706.0
2021-02-15 12:00:00  83800.0  84200.0  84500.0  83300.0  23529706.0
2021-02-16 00:00:00  84500.0  84900.0  86000.0  84200.0  20483100.0
2021-02-16 12:00:00  84500.0  84900.0  86000.0  84200.0  20483100.0
2021-02-17 00:00:00  83900.0  83200.0  84200.0  83000.0  18307735.0
...                      ...      ...      ...      ...         ...
2021-08-11 00:00:00  79600.0  78500.0  79800.0  78500.0  30241137.0
2021-08-11 12:00:00  79600.0  78500.0  79800.0  78500.0  30241137.0
2021-08-12 00:00:00  77100.0  77000.0  78200.0  76900.0  42365223.0
2021-08-12 12:00:00  77100.0  77000.0  78200.0  76900.0  42365223.0
2021-08-13 00:00:00  75800.0  74400.0  76000.0  74100.0  61270643.0

[359 rows x 5 columns]

수익률 계산하기

import pandas as pd

df = pd.read_excel('DB/ss_ex_1.xlsx ', index_col=0, usecols=[0, 1, 4])
df.index = pd.to_datetime(df.index)
df.sort_index(inplace=True)
df['quarter'] = df.index.quarter
print(df)

                 종가       시가  quarter
일자                                   
2021-02-15  84200.0  83800.0        1
2021-02-16  84900.0  84500.0        1
2021-02-17  83200.0  83900.0        1
2021-02-18  82100.0  83200.0        1
2021-02-19  82600.0  82300.0        1
...             ...      ...      ...
2021-08-09  81500.0  81500.0        3
2021-08-10  80200.0  82300.0        3
2021-08-11  78500.0  79600.0        3
2021-08-12  77000.0  77100.0        3
2021-08-13  74400.0  75800.0        3

[127 rows x 3 columns]

df_quarter = df['시가'].resample('q').first().to_frame()
# df_ quarter = df['시가'].groupby(pd.Grouper(freq='q')).first().to_frame()
df_quarter['quarter'] = df_quarter.index.quarter
print(df_quarter)

                 시가  quarter
일자                          
2021-03-31  83800.0        1
2021-06-30  82500.0        2
2021-09-30  80500.0        3

df_daily = df[['종가', 'quarter']].reset_index()
print(df_daily)

            일자       종가  quarter
0   2021-02-15  84200.0        1
1   2021-02-16  84900.0        1
2   2021-02-17  83200.0        1
3   2021-02-18  82100.0        1
4   2021-02-19  82600.0        1
..         ...      ...      ...
122 2021-08-09  81500.0        3
123 2021-08-10  80200.0        3
124 2021-08-11  78500.0        3
125 2021-08-12  77000.0        3
126 2021-08-13  74400.0        3

[127 rows x 3 columns]

r = pd.merge(left=df_daily, right=df_quarter, on='quarter')
r['수익률'] = r['종가'] / r['시가']
r = r.set_index(['quarter', '일자'])
print(r)

                         종가       시가       수익률
quarter 일자                                    
1       2021-02-15  84200.0  83800.0  1.004773
        2021-02-16  84900.0  83800.0  1.013126
        2021-02-17  83200.0  83800.0  0.992840
        2021-02-18  82100.0  83800.0  0.979714
        2021-02-19  82600.0  83800.0  0.985680
...                     ...      ...       ...
3       2021-08-09  81500.0  80500.0  1.012422
        2021-08-10  80200.0  80500.0  0.996273
        2021-08-11  78500.0  80500.0  0.975155
        2021-08-12  77000.0  80500.0  0.956522
        2021-08-13  74400.0  80500.0  0.924224

[127 rows x 3 columns]

'DataFrame' 카테고리의 다른 글

KRX  (0) 2022.04.13
plot  (0) 2022.04.12
컬럼 shift  (0) 2022.04.09
TimeStamp  (0) 2022.04.09
판다스 데이터프레임 (데이터 읽기/ 저장하기)  (0) 2022.04.07

댓글