groupby 함수를 사용하여 데이터 프레임을 분할하고 처리하는 방법

본 기사에 대하여



Python의 pandas를 사용한 데이터 분석에서 groupby 함수는 그룹별로 계산하는 편리한 함수입니다.
내가 자주 사용하는 것은
df.groupby(df['col1'])['col2'].mean()  이나 .describe()  
같은 전통적인 함수이지만,
'분할된 데이터 프레임별로 처리하고 싶다'는 경우가 있으며,
for문과 get_group을 조합하면 그냥 편리하게 처리할 수 있다는 것을 알았으므로 소개합니다.

데이터 준비



groupby_get_group.py
import pandas as pd
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
import numpy as np

iris_dataset = load_iris()
df_iris=pd.DataFrame(iris_dataset.data,columns=iris_dataset.feature_names)
#targetの列を追加
df_iris.loc[:,'target']=iris_dataset.target
#品種名のdictionaryを作成
iris_map=dict(zip([0,1,2],iris_dataset.target_names))
#DataFrameとdictionaryをmap関数でつなぎtarget_namesの列を追加
df_iris.loc[:,'target_names']=df_iris['target'].map(iris_map)




sepal length (cm)
sepal width (cm)
petal length (cm)
petal width (cm)
target
target_names


5.1
3.5
1.4
0.2
0
setosa

4.9
3.0
1.4
0.2
0
setosa

-
-
-
-
-
-

5.7
2.8
4.1
1.3
1
versicolor

-
-
-
-
-
-

6.3
3.3
6.0
2.5
2
virginica


target_names에 groupby 함수를 적용해보기



품종('target_names')마다 데이터 프레임(df_iris)을 분할합니다.
분할한 것을 gp로 했습니다.

groupby_get_group.py
gp = df_iris.groupby('target_names')

분할된 객체의 속성을 살펴보기


In[0]:type(gp)
Out[0]:pandas.core.groupby.generic.DataFrameGroupBy

In[1]:print(gp)
Out[1]:<pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000028788A33708>

groupby를 사용하여 분할된 데이터 세트는 그대로 사용할 수 없습니다.
그래서 for 문을 사용하여 속성 등을 조사해 보겠습니다.

for 문 사용


In[2]:for d_gp in gp:
          print(d_gp)
Out[2]:
 147                6.5               3.0  ...       2     virginica
 148                6.2               3.4  ...       2     virginica
 149                5.9               3.0  ...       2     virginica

 [50 rows x 6 columns])

In[3]:type(d_gp)
out[3]:tuple

분할된 데이터 프레임은 튜플형 변수(d_gp)로서 수납되어 있는 것 같습니다.
여기서 튜플의 내용을 확인하기 위해 다음을 찍어 보면,
In[4]:d_gp[0]
Out[4]:'virginica'

In[5]:d_gp[1]
Out[5]:
     sepal length (cm)  sepal width (cm)  ...  target  target_names
100                6.3               3.3  ...       2     virginica
101                5.8               2.7  ...       2     virginica
102                7.1               3.0  ...       2     virginica
103                6.3               2.9  ...       2     virginica

147                6.5               3.0  ...       2     virginica
148                6.2               3.4  ...       2     virginica
149                5.9               3.0  ...       2     virginica

[50 rows x 6 columns]

와 내보내기 때문에 for문 실행 후 상태는 "target_names"의 세 번째 수준 'virginica'의 데이터 프레임이 d_gp에 대입되어 있는지 확인할 수 있습니다.

따라서 d_gp[1]만 반복해서 처리해도 좋지만, 여기서는 d_gp[0]을 활용하여 get_group 함수에 의해 반복자의 성질을 사용하여 for 루프만으로 특정 데이터 세트를 꺼내고 처리하겠습니다.

#get_group에 의해 튜플에 수납된 데이터를 검색한다.

for 루프에서 데이터 프레임 추출



for 문으로 꺼낼 수있는 것은 2 개의 튜플이며,
튜플의 1번째에는 groupby에 걸친 열의 수준(품종:setosa, versicolor, virginica)이 수납되어,
두 번째에는 각각의 데이터 프레임이 수납되어 있습니다.

이 튜플의 1번째에 수납된 레벨을 변수로서 get_group에서 튜플의 2번째에 수납된 데이터 프레임을 꺼내, 레벨마다 처리를 해 나갑니다.
이것을 각각 꺼내는 것은 for 루프에서 for와 in 사이에 2개의 변수를 준비해 주면 꺼낼 수 있습니다. 즉, 두 번째 변수가 분할된 데이터 프레임입니다.

다음은 setosa, versicolor, virginica 품종별로 분할 된 데이터 프레임
품종을 지정하여 데이터 프레임을 검색하고,
「가쿠의 길이(sepal length)」와 「가쿠의 폭(sepal width)」을 플롯한 것.

groupby_get_group.py
#2021/8/12修正 forループでget_groupを使わない方法に修正
#以下でd_gp[0]はidxとなる
#for d_gp in gp:
#    df_g=gp.get_group(d_gp[0])
for idx,df_g in gp:
    ##ここ以下に分割したデータフレームを使って処理したいことを書く
    fig = plt.figure()
    ax = fig.add_subplot(1,1,1)
    X=df_g[df_g.columns[0]].values
    y=df_g[df_g.columns[1]].values
    #ax.set_title(str.capitalize(d_gp[0])+"  "+\
    ax.set_title(str.capitalize(idx+"  "+\
                 str.capitalize(df_g.columns[0])+\
                 ' vs '+str.capitalize(df_g.columns[1]))
    ax.scatter(X,y,marker='o',color='darkblue',edgecolor="")
    cor=np.corrcoef(X, y)[0,1]
    ax.set_xlabel(str.capitalize(df_g.columns[0]))
    ax.set_ylabel(str.capitalize(df_g.columns[1]))
    ax.text(0.99, 0.01,"correlation:{0:.2}".format(cor),
                    horizontalalignment='right', verticalalignment='bottom',
                    fontsize=12,color="blue",transform=ax.transAxes)
    plt.show()





이상입니다.

결론



처음 Qiita에 게시합니다.
Qiita에게는 도움이 되는 것뿐이었기 때문에, 누군가의 도움이 된다고 생각합니다.

참고문헌



Python 데이터 분석/기계 학습을 위한 기본 코딩! pandas 라이브러리 활용 입문 (impress top gear) (한국어) 단행본(소프트 커버)
ISBN-10: 4295005657
ISBN-13: 978-4295005650

좋은 웹페이지 즐겨찾기