pandas III

Pandas III


Groupby

  • SQL groupby명령어와 같음
  • split → apply → combine
  • 과정을 거쳐 연산함

image.png

In [1]:
import pandas as pd
import numpy as np
In [2]:
# data from:
ipl_data = {
    "Team": [
        "Riders",
        "Riders",
        "Devils",
        "Devils",
        "Kings",
        "kings",
        "Kings",
        "Kings",
        "Riders",
        "Royals",
        "Royals",
        "Riders",
    ],
    "Rank": [1, 2, 2, 3, 3, 4, 1, 1, 2, 4, 1, 2],
    "Year": [2014, 2015, 2014, 2015, 2014, 2015, 2016, 2017, 2016, 2014, 2015, 2017],
    "Points": [876, 789, 863, 673, 741, 812, 756, 788, 694, 701, 804, 690],
}

df = pd.DataFrame(ipl_data)

image.png

In [3]:
df.groupby("Team")["Points"].sum()
Out[3]:
Team
Devils    1536
Kings     2285
Riders    3049
Royals    1505
kings      812
Name: Points, dtype: int64
In [4]:
h_index = df.groupby(["Team", "Year"])["Points"].sum()
h_index
Out[4]:
Team    Year
Devils  2014    863
        2015    673
Kings   2014    741
        2016    756
        2017    788
Riders  2014    876
        2015    789
        2016    694
        2017    690
Royals  2014    701
        2015    804
kings   2015    812
Name: Points, dtype: int64
  • 한 개이상의 column을 묶을 수 있다.


Hierarchical index

  • Groupby 명령의 결과물도 결국은 dataframe
  • 두 개의 column으로 groupby를 할 경우, index가 두개 생성
In [5]:
h_index.index
Out[5]:
MultiIndex([('Devils', 2014),
            ('Devils', 2015),
            ( 'Kings', 2014),
            ( 'Kings', 2016),
            ( 'Kings', 2017),
            ('Riders', 2014),
            ('Riders', 2015),
            ('Riders', 2016),
            ('Riders', 2017),
            ('Royals', 2014),
            ('Royals', 2015),
            ( 'kings', 2015)],
           names=['Team', 'Year'])
In [6]:
h_index["Devils":"Kings"]
Out[6]:
Team    Year
Devils  2014    863
        2015    673
Kings   2014    741
        2016    756
        2017    788
Name: Points, dtype: int64


unstack

  • Group으로 묶어진 데이터를 matrix 형태로 전환해준다.
In [7]:
h_index.unstack()
Out[7]:
Year 2014 2015 2016 2017
Team
Devils 863.0 673.0 NaN NaN
Kings 741.0 NaN 756.0 788.0
Riders 876.0 789.0 694.0 690.0
Royals 701.0 804.0 NaN NaN
kings NaN 812.0 NaN NaN
In [8]:
h_index.unstack().stack()
Out[8]:
Team    Year
Devils  2014    863.0
        2015    673.0
Kings   2014    741.0
        2016    756.0
        2017    788.0
Riders  2014    876.0
        2015    789.0
        2016    694.0
        2017    690.0
Royals  2014    701.0
        2015    804.0
kings   2015    812.0
dtype: float64
  • 여기서 다시 stack()하면 다시 묶어준다.


resetindex

  • index를 column으로 바뀐다.
In [9]:
h_index.reset_index()
Out[9]:
Team Year Points
0 Devils 2014 863
1 Devils 2015 673
2 Kings 2014 741
3 Kings 2016 756
4 Kings 2017 788
5 Riders 2014 876
6 Riders 2015 789
7 Riders 2016 694
8 Riders 2017 690
9 Royals 2014 701
10 Royals 2015 804
11 kings 2015 812


swaplevel

  • Index level을 변경할 수 있다.
In [10]:
h_index.swaplevel()
Out[10]:
Year  Team  
2014  Devils    863
2015  Devils    673
2014  Kings     741
2016  Kings     756
2017  Kings     788
2014  Riders    876
2015  Riders    789
2016  Riders    694
2017  Riders    690
2014  Royals    701
2015  Royals    804
      kings     812
Name: Points, dtype: int64
In [11]:
h_index.swaplevel().sort_index(level=1)
Out[11]:
Year  Team  
2014  Devils    863
2015  Devils    673
2014  Kings     741
2016  Kings     756
2017  Kings     788
2014  Riders    876
2015  Riders    789
2016  Riders    694
2017  Riders    690
2014  Royals    701
2015  Royals    804
      kings     812
Name: Points, dtype: int64
  • index를 sort하고 싶으면 sort_index메서드를 사용한다. level인자는 해당 인덱스의 level로 정렬한다.
In [12]:
h_index.sort_values()
Out[12]:
Team    Year
Devils  2015    673
Riders  2017    690
        2016    694
Royals  2014    701
Kings   2014    741
        2016    756
        2017    788
Riders  2015    789
Royals  2015    804
kings   2015    812
Devils  2014    863
Riders  2014    876
Name: Points, dtype: int64
  • value을 정렬하고 싶으면 sort_values()사용한다.


operations

  • Index level을 기준으로 기본 연산 수행 가능
In [13]:
h_index.std(level=0)
Out[13]:
Team
Devils    134.350288
Kings      24.006943
Riders     88.567771
Royals     72.831998
kings            NaN
Name: Points, dtype: float64
In [14]:
h_index.sum(level=1)
Out[14]:
Year
2014    3181
2015    3078
2016    1450
2017    1478
Name: Points, dtype: int64



grouped

  • Groupby에 의해 Split된 상태를 추출 가능함
In [15]:
grouped = df.groupby("Team")
In [16]:
for name, group in grouped:
    print(name)
    print(group)
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
6  Kings     1  2016     756
7  Kings     1  2017     788
Riders
      Team  Rank  Year  Points
0   Riders     1  2014     876
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
kings
    Team  Rank  Year  Points
5  kings     4  2015     812
In [17]:
grouped.get_group('Devils')
Out[17]:
Team Rank Year Points
2 Devils 2 2014 863
3 Devils 3 2015 673
  • 특정 group의 DataFrame을 가지고 오고 싶으면 get_group을 사용하면 된다.


Aggregation

  • 요약된 통계정보를 추출 한다.
In [18]:
grouped.agg(max)
Out[18]:
Rank Year Points
Team
Devils 3 2015 863
Kings 3 2017 788
Riders 2 2017 876
Royals 4 2015 804
kings 4 2015 812
In [19]:
grouped.agg(sum)
Out[19]:
Rank Year Points
Team
Devils 5 4029 1536
Kings 5 6047 2285
Riders 7 8062 3049
Royals 5 4029 1505
kings 4 2015 812
In [20]:
grouped.agg(np.mean)
Out[20]:
Rank Year Points
Team
Devils 2.500000 2014.500000 768.000000
Kings 1.666667 2015.666667 761.666667
Riders 1.750000 2015.500000 762.250000
Royals 2.500000 2014.500000 752.500000
kings 4.000000 2015.000000 812.000000
  • 인자로는 사용자 정의 함수를 넣을 수도 있다.
In [21]:
grouped['Points'].agg([np.sum,np.mean,np.std])
Out[21]:
sum mean std
Team
Devils 1536 768.000000 134.350288
Kings 2285 761.666667 24.006943
Riders 3049 762.250000 88.567771
Royals 1505 752.500000 72.831998
kings 812 812.000000 NaN
  • 특정 컬럼에 여러개의 function을 Apply할 수도 있다.


Transformation

  • 해당 정보를 변환해 준다.
  • Aggregation과 달리 key값 별로 요약된 정보가 아님
  • 개별 데이터의 변환을 지원함

image.png

In [22]:
score = lambda x: (x - x.mean()) / x.std()
grouped.transform(score)
Out[22]:
Rank Year Points
0 -1.500000 -1.161895 1.284327
1 0.500000 -0.387298 0.302029
2 -0.707107 -0.707107 0.707107
3 0.707107 0.707107 -0.707107
4 1.154701 -1.091089 -0.860862
5 NaN NaN NaN
6 -0.577350 0.218218 -0.236043
7 -0.577350 0.872872 1.096905
8 0.500000 0.387298 -0.770596
9 0.707107 -0.707107 -0.707107
10 -0.707107 0.707107 0.707107
11 0.500000 1.161895 -0.815759
  • transform은 group별 컬럼단위로 인자 함수를 실행하여 개별 데이터에 적용시킨다. 위 코드는 group별로 정규화를 시켜주는 코드이다. (주의!!, 전체값을 정규화하는것이 아니라 group단위로 정규화 시켜준것)
In [23]:
score = lambda x: (x - x.min()) / (x.max() - x.min())
grouped.transform(score)
Out[23]:
Rank Year Points
0 0.0 0.000000 1.000000
1 1.0 0.333333 0.532258
2 0.0 0.000000 1.000000
3 1.0 1.000000 0.000000
4 1.0 0.000000 0.000000
5 NaN NaN NaN
6 0.0 0.666667 0.319149
7 0.0 1.000000 1.000000
8 1.0 0.666667 0.021505
9 1.0 0.000000 0.000000
10 0.0 1.000000 1.000000
11 1.0 1.000000 0.000000


Filteration

  • 특정 정보를 제거하여 보여주는 필터링 기능
  • 특정 조건으로 데이터를 검색할 때 사용
In [24]:
df.groupby("Team").filter(lambda x: len(x) >= 3)
Out[24]:
Team Rank Year Points
0 Riders 1 2014 876
1 Riders 2 2015 789
4 Kings 3 2014 741
6 Kings 1 2016 756
7 Kings 1 2017 788
8 Riders 2 2016 694
11 Riders 2 2017 690
  • filter안에는 boolean 조건이 존재해야한다.
  • 여기서 x로 들어오는 인자는 groupedDataFrame객체가 들어온다.
  • len(x)는 grouped된 dataframe의 개수
In [25]:
df.groupby("Team").filter(lambda x: x["Points"].mean() > 700)
Out[25]:
Team Rank Year Points
0 Riders 1 2014 876
1 Riders 2 2015 789
2 Devils 2 2014 863
3 Devils 3 2015 673
4 Kings 3 2014 741
5 kings 4 2015 812
6 Kings 1 2016 756
7 Kings 1 2017 788
8 Riders 2 2016 694
9 Royals 4 2014 701
10 Royals 1 2015 804
11 Riders 2 2017 690

'AI > 이론' 카테고리의 다른 글

matplotlib II  (0) 2021.01.29
matplotlib I  (0) 2021.01.29
확률론 맛보기  (0) 2021.01.28
Pandas IV  (0) 2021.01.28
딥러닝 학습방법 이해하기  (0) 2021.01.27
Pandas II  (0) 2021.01.27
Pandas I  (0) 2021.01.27
경사하강법 II  (0) 2021.01.26

+ Recent posts