이번 포스팅은 Pandas를 이용한 데이터 분석을 할 때, 균할분등 혹은 그러한 작업 또 다른 그룹을 생성할 때 많이 사용되는 메소드를 소개한다.
#%%
import numpy as np
import pandas as pd
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
pd.set_option('display.float_format', lambda x: '%.3f' % x)
pd.set_option('max_columns', None)
df = pd.read_csv()
#%%
#1. qcut <-Group내 데이터 갯수를 기준으로 Grouping(SAME number of members in each group)
pd.qcut(df['PER(배)'], 3, labels=[1,2,3]) #PER기준으로 정확히 3등분
df.loc[:, "PER_Score2"] = pd.qcut(df['PER(배)'], 10, labels = range(1,11))
df.head()
df['PER_Score2'].value_counts()
df['PER_Score2'].hasnans
df['PER_Score2'].isna().sum()
df['PER_Score2'].dtype #'category' type: A string variable consisting of only a few different values
df = df.dropna(subset=['PER(배)'])
df['PER_Score2'].isna().sum()
#%%
#2. Split - Apply - Combine
# NA값 제거
df = pd.read_csv()
df = df.dropna()
g_df = df.copy()
g_df.head()
# Group생성
g_df['rtn'] = g_df['price2'] / g_df['price'] -1
g_df.loc[:,'PER_score'] = pd.qcut(g_df['PER(배)'], 10, labels = range(1, 11))
g_df.loc[:,'PBR_score'] = pd.qcut(g_df['PER(배)'], 10, labels = range(1, 11))
g_df.set_index('ticker', inplace=True)
# groupby() & aggreation
# groupby의 경우 실제 그룹을 생성하지 않고, 그룹이 생성될 수 있는지 확인하는 정도가지
# 3. groupby object 살펴보기
g_df.groupby('PER_score')
g_df_obj = g_df.groupby(['PBR_score', 'PER_score'])
g_df_obj
g_df['PBR_score'].nunique()
g_df['PER_score'].nunique()
type(g_df_obj.size())
g_df_obj.size().head()
# Multi-level index를 가진 Series indexing하는 법
g_df_obj.size().loc[1]
g_df_obj.size().loc[(1,1)]
type(g_df_obj.groups)
g_df_obj.groups.keys()
g_df_obj.groups.values()
for name, group in g_df_obj:
print(name)
group.head(2)
# 4. aggreggation (반드시 aggregating 기능이 있는 함수를 써야함) <- aggregation 함수가 아닌 경우에는 error 발생시킴
### 주의: nan은 groupby시 자동으로 filter out 되기 때문에, 미리 전처리 다 하는게 좋음
g_df.groupby('PBR_score').agg(
{
"rtn" : "mean" # = np.mean
}
)
pbr_rtn_df = g_df.groupby("PBR_score").agg({"rtn" : "mean"})
per_rtn_df = g_df.groupby("PER_score").agg({"rtn" : "mean"})
pbr_rtn_df.head()
# 다양한 방법으로 진행하기 (같은 결과)
g_df.groupby("PER_score")['rtn'].agg('mean').head()
g_df.groupby("PER_score")['rtn'].agg(np.mean).head()
g_df.groupby("PER_score")['rtn'].mean().head()
# return type이 다를 수 있음에 주의
g_df.groupby("PER_score")['rtn'].agg("mean").head(2) # Series로 return
g_df.groupby("PER_score")[['rtn']].agg("mean").head(2) # DataFrame으로 return
# 2개 이상의 컬럼에 대해 aggregation
g_df.groupby('PER_score')[['rtn', 'PBR(배)']].agg("mean").head(2)
# 2게 이상의 aggregation
g_df.groupby("PER_score")[['rtn', 'PBR(배)']].agg('mean','std').head(2)
# 2개 이상의 컬럼 & 각각에 대해 다른 aggregation
g_df.groupby("PBR_score").agg(
{
'rtn' : ['mean', 'std'],
'PER(배)' : ['min']
}
)
pbr_rtn_df.plot(kind = "bar")
per_rtn_df.plot(kind = "bar")
a = g_df.groupby(["PBR_score", "PER_score"])['rtn', 'ROE(%)'].agg(['sum', 'mean'])
### `as_index = False` : group cols들이 index가 아니라 하나의 col이 됨 (aggregate하고 reset_index()를 취한 것)
a = g_df.groupby(["PER_score"] ).agg({'rtn': ['mean', 'std']}).head(2)
b = g_df.groupby(["PER_score"], as_index=False).agg({'rtn': ['mean', 'std']}).head(2)
a.index
a.columns
b.index
b.columns
### Multi-index columns을 하나로 병합하기
g_df1 = g_df.groupby(["PBR_score", "PER_score"])\
.agg(
{
'rtn': ['mean', 'std', 'min', 'max'],
'ROE(%)': [np.mean, 'size', 'nunique', 'idxmax']
}
)
g_df1.head()
level0 = g_df1.columns.get_level_values(0)
level1 = g_df1.columns.get_level_values(1)
g_df1.columns = level0 + '_' + level1
g_df1
g_df1 = g_df1.reset_index()
'Python > Pandas' 카테고리의 다른 글
Pandas _ concat & pivot (0) | 2021.01.13 |
---|---|
Pandas _ row 추가하기 (loc & append) (0) | 2021.01.12 |
Pandas _ Category using .loc & cut Method (0) | 2021.01.05 |
Pandas _ About Nan (0) | 2021.01.04 |
Pandas _ 1. 추출(정렬) _ 2. Boolean Selection _ 3. isin() (0) | 2021.01.03 |