본문 바로가기

Quant

Quant : Pandas - API(2)

 

Boolean Selection

 

Boolean Series

- 직접 인덱싱을 하는게 아니라, 조건식으로 해당되는 컬럼만 추출 (>, <, ==)

tmp_series = pd.Series({"a":1, "b":2})
tmp_series > 2

# a    False
# b    False
# dtype: bool

 

DataFrame 내에서 Boolean Series 만들기

a = df['순이익률(%)'] > df['영업이익률(%)']
# 동일한 index(row)에 대해 비교
a.head()

# 0    False
# 1    False
# 2    False
# 3    False
# 4    False
# dtype: bool

 

Boolean series로 indexing 하기

df[a] // a : 위에서 선언한 boolean series

df.shape
# (681, 15)

df[a].shape // a가 True인 것만 가져왔기에, 사이즈가 변경됨
# (142, 15)
// df.loc[a].shape : df.loc[a] == df.loc[[9, 10, 13 ...]] true인 rows

 


 

Multiple boolean series

con1 = df["순이익률"] > df["영업이익률"]
con2 = df["PBR"] < 1

final_con = (con1 & con2) # Python 'and', 'or' 대신에 &, | 사용

 

일부 종목의 데이터만 가져오는 방법

1) multiple boolean series 이용

cond1 = df['종목명'] == "삼성전자"
cond2 = df['종목명'] == "현대건설"
cond3 = df['종목명'] == "삼성물산"

final_con = cond1 | cond2 | cond3
df[final_con]

2) index화 해서 loc으로 row-wise indexing을 이용해서 가져오는 방법

tmp_df = df.set_index('종목명')
tmp_df.head()

tmp_df.loc[['삼성전자', '현대건설', "삼성물산"]]

3) .isin() 함수 이용

name_list = ["삼성전자", "현대건설", "삼성물산"]
cond = df['종목명'].isin(name_list)
df[cond]

# df[df['종목명'].isin(name_list)].head(2)
# df.loc[df['종목명'].isin(name_list)].head(2)
# df.loc[df['종목명'].isin(name_list), ['종목명', 'ROA(%)', 'ROE(%)']].head(2)

.all()

- True : 해당 시리즈가 전부 True

- False : True가 아닌 것이 1개 이상 있다

(df["순이익률"] > 0).all()

 

.any()

- True : True인것이 1개 이상 있다.

- False : 해당 시리즈의 모든 값이 False

(df["순이익률"] > 0).any()

 

 

 

example : 가장 큰 5개 섹터에 해당되는 종목 추출

a = pd.read_csv("my_data/symbol_sector.csv", index_col=0)

a['Sector'].value_counts().nlargest(5)
# 기타 금융업           110
# 자동차 신품 부품 제조업     46
# 의약품 제조업           44
# 전자부품 제조업          38
# 1차 철강 제조업         38
# Name: Sector, dtype: int64

top_5_sector_list = a['Sector'].value_counts().nlargest(5).index
# Index(['기타 금융업', '자동차 신품 부품 제조업', '의약품 제조업', '전자부품 제조업', '1차 철강 제조업'], dtype='object')

a[a['Sector'].isin(top_5_sector_list)]

 

 


연산 Arithmetic

- DataFrame는 기준이 columns

- Series는 기준이 index

- 별도의 명시가 없다면 Series의 index가 DataFrame의 columns에 맞춰짐

 

axis

연산은 기본적으로 "axis를 변형(줄이거나 늘리는)하는 방식"

몇번째 axis를 없앨 것인가로 이해하면 편하다 (axis = 0 ...)

a = np.array([1,2,3])
b = np.array([1,2,3])

a+b
# array([2, 4, 6])

np.sum([a,b], axis=0)
# array([2,4,6])

np.sum([a,b], axis=1)
# array([6,6])


# Before : 2차원 이상 axis가 늘어날 때는 이해가 어려움
#      0  1  2
#   0  [1, 2, 2],
#   1  [1, 2, 2]
#

# After : n차원 axis도 이해 可
# axis=0 --->       0            1
# axis=1 --->    0  1  2      0  1  2
#            [  [1, 2, 2],   [1, 2, 2] ]

# axis=0 --->              0                        1
# axis=1 --->      0       1     2          0       1      2
# axis=2 --->     0  1    0, 1    0        0, 1    0, 1    0, 1
#            [  [[1, 2], [2, 4], [2]],   [[1, 2], [2, 2], [2, 2]] ]

 

 

* Note: shift+tab을 이용해서 주석 설명을 보는 것이 가장 정확함

 

* Example : 모멘텀(추세) 계산 

b = pd.read_csv("my_data/multi_price.csv", index_col=[0])
b.loc["2018-08-09"]
momentum_series = b.loc["2018-08-09"] / b.loc["2017-08-09"] - 1
momentum_series.nlargest(3)

# DB       0.142
# DB금융투자   0.118
# CJ헬로     0.088
# dtype: float64

Handling nan

None == None
# True

np.nan == np.nan
# False

5 < np.nan
# False

5 >= np.nan
# False

5 == np.nan
# False

np.nan != 5
# True

 

nan이 있을 때의 Boolean Series

df1['b'] == df1['b']
# 0    False
# 1     True
# 2    False
# Name: b, dtype: bool

df1.ge(2)   # Same with (df1 >= 2)
df1.le(2) # ge : greater or equal / le : less or equal

 

Nan Checking

 

For Series

df['순이익률(%)'].hasnans
# True

# Generate boolean series
df['순이익률(%)'].isnull()
# 0      False
# 1      False
# 2      False
# 3      False
# 4      False
#        ...  
# 676    False
# 677    False
# 678    False
# 679    False
# 680    False
# Name: 순이익률(%), Length: 681, dtype: bool

df['순이익률(%)'].isna().any()
# True

df['순이익률(%)'].isna().sum()
# 1

 

For DataFrame

a = df.isnull()
a.any(axis=0)
# 종목명          False
# 매출액(억원)       True
# 영업이익률(%)      True
# 순이익률(%)       True
# 당기순이익(억원)     True
# ROE(%)        True
# ROA(%)        True
# ROIC(%)       True
# EPS(원)       False
# BPS(원)       False
# SPS(원)       False
# PER(배)        True
# PBR(배)       False
# PSR(배)        True
# price        False
# price2       False
# dtype: bool

df.isnull().any().any()
# True

df.isnull().any().all()
# False

* 두 개의 DataFrame이 같은지 판단하라면, == 이 아니라 .equals()를 사용하자

df1['b'].equals(df1['b'])
# True

 

'Quant' 카테고리의 다른 글

Quant : Pandas - 데이터 합치기  (0) 2022.04.05
Quant : Pandas - Grouping  (0) 2022.03.27
Quant : Pandas - API (1)  (0) 2022.03.14
Quant : Pandas - Series & DataFrame  (0) 2022.03.12
Quant : 사전 계획  (0) 2022.03.08