퀀트

03. Pandas : Series, DataFrame

만 기 2022. 11. 30. 18:06

Pandas

Panel Data System

금융 데이터 분석에 적합한 도구

1~2차원의 표 형태의 데이터

행과 열에 이름을 붙일 수 있다. (index와 columns)

 

Series

1차원 데이터 표현

행 X 값 데이터

데이터 배열에 이름과 각 데이터의 라벨(인덱스)를 붙임

 

Pandas 임포트

import pandas as pd

 

Series의 인덱스와 이름 보기

# Series의 인덱스 보기
my_series.index

# Series의 이름 보기
my_series.name

 

Series 접근

.loc[]

# my_series.loc[데이터라벨 (or slice)]
my_series.loc['2020-09-15']
  • Series에서 데이터의 라벨이름으로 접근한다.
  • Slice 할 경우 끝을 포함한다.

 

.iloc[]

# my_series.iloc[인덱스 (or slice)]
my_series.iloc[4]
  • Series에서 인덱스 배열 번호로 접근한다.
  • Slice 할 경우 끝을 포함하지 않는다.

 

slice

# loc slicing
my_series.loc['2020-09-15':'2020-09-17']
# 결과
# 2020-09-15 61000.0
# 2020-09-16 61000.0
# 2020-09-17 59500.0
# Name: A005930, dtype: float64

# iloc slicing
my_series.iloc[4:7]     # 끝을 포함하지 않으므로 결과 똑같음.

 

연산과 broadcasting

# 연산
my_series.iloc[4:] + my_series.iloc[4:]
# 결과
# 2020-09-15 122000.0
# 2020-09-16 122000.0
# 2020-09-17 119000.0
# 2020-09-18 118600.0
# Name: A005930, dtype: float64

# broadcasting
my_series.loc['2020-09-15'::2] +30000
# 결과
# 2020-09-15 91000.0
# 2020-09-17 89500.0
# Name: A005930, dtype: float64

 

aggregation

my_series.iloc[4:].mean()

 

Series 생성

pd.Series()

new_sr = pd.Series([11,22,3,45], name='apple', index=['a','b','xs','e11'])
new_sr
# 결과
# a     11
# b     22
# xs     3
# e11   45
# Name: apple, dtype: int64
  • name과 index는 생략 가능함
  • name은 기본값 None
  • index는 0,1,2,3,.. 으로 자동지정

 

DataFrame

2차원 데이터

행 X 열

여러 개의 Series를 묶어서 만든 형태 ( 하나 씩 떼어놓으면 Series가 된다.)

각 **Series의 name은 DataFrame에서는 열(column)**이 된다.

 

DataFrame 접근

.loc[행, 열]

# my_df.loc[라벨 이름 (or slice), column 이름 (or slice)]
my_df.loc['2020-09-15', 'A005930']

# [라벨이름, 컬럼이름slice]로 접근 -> series 반환
my_df.loc['2020-09-15', 'A005930':'A005950']

# [라벨이름slice, 컬럼이름]로 접근 -> series 반환
my_df.loc['2020-09-15':'2020-09-18', 'A005930']

# [라벨이름slice, 컬럼이름slice]로 접근 -> dataframe 반환
my_df.loc['2020-09-14':'2020-09-18':2, 'A005940':'A005980']
  • dataframe에서 라벨이름과, 컬럼이름으로 접근한다.
  • slice 할 때 끝을 포함한다.

 

.iloc[행, 열]

# my_df.iloc[인덱스 배열 번호 (or slice), column 번호 (or slice)]
my_df.loc[2, 4]
  • dataframe에서 인덱스 번호와 컬럼 번호로 접근한다.
  • slice 할 때 끝을 포함하지않는다.

⇒ 추출할 shape가 1차원( (1,m) 또는 (n,1) ) 일 경우 Series가 반환되며, 그 외 dataframe을 반환한다.

 

slice

# 모든 원소 지칭
my_df.iloc[5, :]
# 결과
# Symbol
# A005930     61000.0
# A005940      9530.0
# A005950      9080.0
# A005960     11250.0
# A005980       617.0
# A005990      8180.0
# Name: 2020-09-16, dtype: float64

# shape 보기
my_df.iloc[5, :].shape
# 결과
# (6,)

# dataframe으로 가져오기
my_df.iloc[5:, ::3]
# 인덱스는 5번부터, 컬럼은 처음부터 3칸간격

# 응용
my_df.iloc[::4].loc[:, 'A005950':]

my_df.loc['2020-09-09'::4].iloc[:, 2:]

 

Broadcasting

my_df_2 = my_df.loc[:'2020-09-11', 'A005960':]

# broadcasting
my_df_2 * 1.30     # 1.30 = 30% 상승

 

Aggregation

my_df_2.mean(axis=0)       # my_df_2는 dataframe이지만 세로축 평균값을 구하면 Series가 됨
# 결과
# Symbol
# A005960     11066.666667
# A005980       671.000000
# A005990      8023.333333
# dtype: float64

 

실습

!wget

웹 사이트에서 파일을 다운로드 할 수 있는 리눅스 명령어

# 데이터 다운로드
!wget "<https://gist.githubusercontent.com/solaris33/b9cf16a1656b52574ae3fcd9163d91ca/raw/c177ef2580f89c664e8291d1b7b92be8430a9cd1/stock.adj_close.csv>" -O "stock.adj_close.csv"

colab에서는 사용가능하나 다른 환경에서 명령어를 사용하려면

import wget
url = "<https://gist.githubusercontent.com/solaris33/b9cf16a1656b52574ae3fcd9163d91ca/raw/c177ef2580f89c664e8291d1b7b92be8430a9cd1/stock.adj_close.csv>" -O "stock.adj_close.csv"
wget.download(url)

 

임포트

import numpy as np
import pandas as pd

 

csv 파일 변수에 저장하여 사용하기

주가_데이터 = pd.read_csv('./stock.adj_close.csv', index_col=0)

         2018-06-01  2018-06-04  2018-06-05  2018-06-07  2018-06-08  \\
Symbol                                                                
A000020     11550.0     11750.0     11700.0     11650.0     11500.0   
A000030     15500.0     15950.0     16050.0     16500.0     16600.0   
A000040      2992.0      3021.0      3025.0      3069.0      3045.0   
A000050     13200.0     13550.0     13600.0     13800.0     13800.0   
A000060     20050.0     20050.0     20150.0     20050.0     20400.0
  • pd.read_csv() : pandas 패키지의 read_csv 옵션을 사용하여 csv 파일 읽기
  • 첫번째 인자는 파일 경로 : ./ 현재 폴더에서 stock.adj_close.csv 파일 이름을 찾는다.
  • index_col=0 은 pandas로 csv 파일을 읽어오면 인덱스 열이 자동으로 첫번째 컬럼으로 들어가게 되는데, index_col=0으로 인덱스 컬럼을 제거할 수 있다.

 

.loc 사용하여 일부 데이터 series로 저장

my_series = 주가데이터.loc['A005930']['2020-09-09':'2020-09-18']

2020-09-09    58400.0
2020-09-10    59200.0
2020-09-11    59000.0
2020-09-14    60400.0
2020-09-15    61000.0
2020-09-16    61000.0
2020-09-17    59500.0
2020-09-18    59300.0
Name: A005930, dtype: float64

 

index, name, type

my_series.index
# Index(['2020-09-09', '2020-09-10', '2020-09-11', '2020-09-14', '2020-09-15', '2020-09-16', '2020-09-17', '2020-09-18'], dtype='object')

my_series.name
# A005930

type(my_series)
# pandas.core.series.Series

 

DataFrame 뽑기

my_df = 주가_데이터.T.loc['2020-09-09':'2020-09-18','A005900':'A006000']
  • .T는 행과 열을 바꾸는 pandas 옵션이다.

 

<연습문제 3>

my_df에서 A005930과 A005950 종목의 2020-09-10 ~ 2020-09-17 의 주가를 이틀 간격으로 뽑아보세요

my_df.loc['2020-09-10':'2020-09-17':2, 'A005930':'A005950':2]

이렇게도 할 수 있지만 원하는 종목을 직접 리스트에 넣을 수 있다.

my_df.loc['2020-09-10':'2020-09-17':2, ['A005930', 'A005950']]

 

<연습문제 6>

my_df에서 모든 종목의 2020-09-17 ~ 2020-09-24 기간의 수익률을 구해보세요 (% 단위)(끝날의 주가 - 처음날의 주가) / (처음날의 주가)

my_df = 주가_데이터.T.loc['2020-09-17':'2020-09-24', 'A005900':'A006000']

((my_df.loc['2020-09-24'] - my_df.loc['2020-09-17']) / my_df.loc['2020-09-17']) * 100

수익률(%) = ( ( 매도금액 - 매수금액 ) / 매수금액 ) * 100