[Python.Pandas] Groupby 이해하기 - 2편

2020. 12. 24. 05:00Python과 머신러닝/Pandas 데이터 분석

0. 이전 포스트

 

[Python.Pandas] Groupby 함수 이해하기 - 1편

1. Groupby 란? GroupBy란, 주어진 데이터를 그룹 별로 구분하여 데이터를 보기 위해 사용되는 함수이다. SQL을 해본 사람이라면 SQL의 Groupby와 동일한 동작을 하는 함수이다. Excel의 Pivot Table과도 유사

coding-grandpa.tistory.com

 

1. .swap_level과 .sort_index

In [10]:h_index.swaplevel()
Out[10]:Year Team 
        2014 Devils 863 
        2015 Devils 673
        2014 Kings 741
        2015 Kings 812
        2016 Kings 756
        2017 Kings 788
        2014 Riders 879
        2015 Riders 789
        2016 Riders 694
        2017 Riders 690
        2014 Royals 701
        2015 Royals 804
        Name: Points, dtype: int64
        
In [11]:h_index.swaplevel().sort_index(level=0)
Out[11]:Year Team
        2014 Devils 863
             Kings 741
             Riders 879
             Royals 701
        2015 Devils 673
             Kings 812
             Riders 789
             Royals 804
        2016 Kings 756
             Riders 694 
        2017 Kings 788 
             Riders 690 
        Name: Points, dtype: int64
  • .swaplevel() 함수는 기존의 팀->연도 순서로 구분이 되어있던 것을 연도->팀 순서로 Group의 순서를 swap하는 함수이다.
  • 이는 단순히 Swap만 해주기 때문에, 연도별로 정렬하기 위해서는 .sort_index() 함수를 통해 정리가 필요하다.
  • 이 두 동작을 수행하고나면 Out[11]과 같이 연도->팀별 총점을 볼 수 있게 된다.

 

2. GroupBy 부가 기능 (groupby의 name/group, .get_group() 함수)

In [12]:grouped = df.groupby('Team')

In [13]:for name, group in grouped: 
            print(name)
            print(group)
Out[13]:
Devils 
    Team     Rank   Year   Points 
2   Devils   2      2014   863 
3   Devils   3      2015   673 

Kings 
    Team     Rank   Year   Points 
4   Kings    3      2014   741 
5   Kings    4      2015   812 
6   Kings    1      2016   756 
7   Kings    1      2017   788 

Riders 
    Team     Rank   Year   Points 
0  Riders    1      2014   879 
1  Riders    2      2015   789 
8  Riders    2      2016   694 
11 Riders    2      2017   690 

Royals
    Team     Rank   Year   Points 
9   Royals   4      2014   701
10  Royals   1      2015   804

In [14]:grouped.get_group('Riders')
Out[14]:
    Team     Rank   Year   Points 
0   Riders   1      2014   879
1   Riders   2      2015   789
8   Riders   2      2016   694
11  Riders   2      2017   690
  • groupby 한 결과물에는 name과 group이라는 변수가 자동으로 생성되어, 각 Group의 이름과, group의 정보를 담고 있다.
  • Out[13]과 같이 각각 출력하면 'Devils'라는 이름과, 'Group' 내의 정보가 있다.
  • In[14]의 .get_group() 함수는 팀별로 grouped 된 정보로부터 'Riders' 팀의 정보만 추출하겠다는 함수이다.

 

3. .agg 함수를 통해 1개~n개 lambda 함수 적용하기

In [15]:grouped.agg(max)
Out[15]:
        Rank  Year    Points
Team
Devils  3     2015    863
Kings   4     2017    812
Riders  2     2017    879
Royals  4     2015    804

In [16]:grouped["Points"].agg([np.sum, np.mean, np.std]) # 특정 Series에 여러 함수를 apply 할 수 있다.
Out[16]:
         sum    mean   std
Team
Devils   1536  768.00  134.350288
Kings    3097  774.25  31.899582
Riders   3052  763.00  89.855439
Royasl   1505  752.50  72.831998
  • .agg 함수각 Group별로 Series 별로 함수를 적용하여 결과를 추출할 때 사용되는 함수이다.
  • In[15]의 예시에서는 팀별로 Rank/Year/Points의 Max 값을 찾기 위한 함수이고, 그에 대한 결과를 Out[15]에서 확인할 수 있다.
  • 이와 같이 .agg 함수를 통해서 각 Group/Series 별로 함수 적용이 가능한데, 한 번에 한 함수만 적용하는 것이 아니라, 여러 함수를 적용할 수 있다.
  • In[16]에서는 팀별 점수에 대해서 sum / mean / std를 추출하라는 command 이고,
  • 이에 대한 결과를 Out[16]에서 확인할 수 있다.

 

4. GroupBy .transform : lambda 함수를 통한 pandas 데이터 변형하기

In [17]:normalize = lambda x:(x-x.mean())/x.std()

In [18]:grouped.transform(normalize)
Out[18]:
     Rank        Year        Points
0    -1.500000   -1.161895    1.290962
1     0.500000   -0.387298    0.289354
2    -0.707107   -0.707107    0.707107
3     0.707107    0.707107   -0.707107
4     0.500000   -1.161895   -1.042333
5     1.166667   -0.387298    1.183401
6    -0.833333    0.387298   -0.572108
7    -0.833333    1.161895    0.431040
8     0.500000    0.387298   -0.767900
9     0.707107   -0.707107   -0.707107
10   -0.707107    0.707107    0.707107
11    0.500000    1.161895   -0.812416
  • .agg와 유사하게 .transform을 통해서 lambda 함수를 전달하고, 그 결과값으로 기존 dataframe의 데이터를 변형할 수 있다.
  • 위 예제는 정규화 함수를 lambda 함수 normalize로 정의하고, 이를 grouped에 적용하여 데이터를 변형한 결과이다.

 

5. .filter 함수 사용하기

In [19]:df.groupby('Team').sum()
Out[19]:
       Rank  Year   Points
Team
Devils 5     4029   1536
Kings  9     8062   3097
Riders 7     8062   3052
Royals 5     4029   1505

In [20]:df.groupby('Team').filter(lambda x:x["Points"].sum()>3000)
Out[20]:
       Rank  Year   Points
Team
Riders  1    2014    879
Riders  2    2015    789
Kings   3    2014    741
Kings   4    2015    812
Kings   1    2016    756
Kings   1    2017    788
Riders  2    2016    694
Riders  2    2017    690
  • Filter 함수를 통해 원하는 기준을 전달하면, 기준에 해당하는 Data만 추출할 수 있다.
  • Out[19]에 보면 3000점을 넘는 팀은 Kings와 Riders 임을 확인할 수 있다.
  • 이를 In[20]의 기준으로 전달하면, 전체 데이터 중 Kings와 Riders에 해당하는 정보만 나오는 것을 확인할 수 있다.

 

6. 관련 포스트

 

[Python.Pandas] Groupby 실습 / 데이터 분석 (Date/Time 데이터 분석)

0. 이전 글 Groupby와 관련한 기초는 이전 포스트에 정리하여, 해 포스트보다 더 기본부터 보고 싶다면 아래 글들을 읽는 것도 좋다. 2020/11/17 - [Python과 머신러닝/웹 데이터 추출] - [Python.Web] wget으로

coding-grandpa.tistory.com