데이터는 다음과 같습니다.
tips[:6]
total_bill tip smoker day time size tip_pct
0 16.99 1.01 No Sun Dinner 2 0.059447
1 10.34 1.66 No Sun Dinner 3 0.160542
2 21.01 3.50 No Sun Dinner 3 0.166587
3 23.68 3.31 No Sun Dinner 2 0.139780
4 24.59 3.61 No Sun Dinner 4 0.146808
5 25.29 4.71 No Sun Dinner 4 0.186240
이후 pivot_table을 day와 smoker에 대해 설정하고, 함수를 적용하면
tips.pivot_table(index=['day', 'smoker'])
size tip tip_pct total_bill
day smoker
Fri No 2.250000 2.812500 0.151650 18.420000
Yes 2.066667 2.714000 0.174783 16.813333
Sat No 2.555556 3.102889 0.158048 19.661778
Yes 2.476190 2.875476 0.147906 21.276667
Sun No 2.929825 3.167895 0.160113 20.506667
Yes 2.578947 3.516842 0.187250 24.120000
Thur No 2.488889 2.673778 0.160298 17.113111
Yes 2.352941 3.030000 0.163863 19.190588
groupby의 단점이 무엇이었죠?
바로 인터페이스가 불편하다는 점이었지만, pivot_table은 이를 해결한 함수입니다.
pivot_table은 groupby와 reshape를 활용하여 계층적 인덱싱을 만들어냅니다.
참고로 default 계산으로 mean 계산을 합니다.
tips.pivot_table(['tip_pct', 'size'], index=['time', 'day'],
columns='smoker')
size tip_pct
smoker No Yes No Yes
time day
Dinner Fri 2.000000 2.222222 0.139622 0.165347
Sat 2.555556 2.476190 0.158048 0.147906
Sun 2.929825 2.578947 0.160113 0.187250
Thur 2.000000 NaN 0.159744 NaN
Lunch Fri 3.000000 1.833333 0.187735 0.188937
Thur 2.500000 2.352941 0.160311 0.163863
앞에 [tip_pct, size]를 넣음으로써, 해당 데이터들만 보여줍니다.
tips.pivot_table(['tip_pct', 'size'], index=['time', 'day'],
columns='smoker', margins=True)
size tip_pct
smoker No Yes All No Yes All
time day
Dinner Fri 2.000000 2.222222 2.166667 0.139622 0.165347 0.158916
Sat 2.555556 2.476190 2.517241 0.158048 0.147906 0.153152
Sun 2.929825 2.578947 2.842105 0.160113 0.187250 0.166897
Thur 2.000000 NaN 2.000000 0.159744 NaN 0.159744
Lunch Fri 3.000000 1.833333 2.000000 0.187735 0.188937 0.188765
Thur 2.500000 2.352941 2.459016 0.160311 0.163863 0.161301
All 2.668874 2.408602 2.569672 0.159328 0.163196 0.160803
margins를 통하여 전체에 대한 평균도 계산할 수 있습니다.
tips.pivot_table('tip_pct', index=['time', 'smoker'], columns='day',
aggfunc=len, margins=True)
day Fri Sat Sun Thur All
time smoker
Dinner No 3.0 45.0 57.0 1.0 106
Yes 9.0 42.0 19.0 NaN 70
Lunch No 1.0 NaN NaN 44.0 45
Yes 6.0 NaN NaN 17.0 23
All 19.0 87.0 76.0 62.0 244
간단하네요.
tips.pivot_table('tip_pct', index=['time', 'size', 'smoker'],
columns='day', aggfunc='mean', fill_value=0)
day Fri Sat Sun Thur
time size smoker
Dinner 1 No 0.000000 0.137931 0.000000 0.000000
Yes 0.000000 0.325733 0.000000 0.000000
2 No 0.139622 0.162705 0.168859 0.159744
Yes 0.171297 0.148668 0.207893 0.000000
3 No 0.000000 0.154661 0.152663 0.000000
... ... ... ... ... ... ...
Lunch 3 Yes 0.000000 0.000000 0.000000 0.204952
4 No 0.000000 0.000000 0.000000 0.138919
Yes 0.000000 0.000000 0.000000 0.155410
5 No 0.000000 0.000000 0.000000 0.121389
6 No 0.000000 0.000000 0.000000 0.173706
결측치에 대해서 0을 채워 넣은 모습입니다.
Cross-Tabulations : Crosstab
from io import StringIO
data = """\
Sample Nationality Handedness
1 USA Right-handed
2 Japan Left-handed
3 USA Right-handed
4 Japan Right-handed
5 Japan Left-handed
6 Japan Right-handed
7 USA Right-handed
8 USA Left-handed
9 Japan Right-handed
10 USA Right-handed"""
data = pd.read_table(StringIO(data), sep='\s+')
data
Sample Nationality Handedness
0 1 USA Right-handed
1 2 Japan Left-handed
2 3 USA Right-handed
3 4 Japan Right-handed
4 5 Japan Left-handed
5 6 Japan Right-handed
6 7 USA Right-handed
7 8 USA Left-handed
8 9 Japan Right-handed
9 10 USA Right-handed
pd.crosstab(data.Nationality, data.Handedness, margins=True)
Handedness Left-handed Right-handed All
Nationality
Japan 2 3 5
USA 1 4 5
All 3 7 10
데이터를 축약하고 싶을 때, pivot_table을 이용할 수 있지만,
판다스에서는 crosstab을 이용하여 더 간단하게 축약할 수 있습니다.
지역을 인덱스로 하며, 어느 손잡이인지를 열로 하여 통계를 냅니다.
pd.crosstab([tips.time, tips.day], tips.smoker, margins=True)
smoker No Yes All
time day
Dinner Fri 3 9 12
Sat 45 42 87
Sun 57 19 76
Thur 1 0 1
Lunch Fri 1 6 7
Thur 44 17 61
All 151 93 244
시간과 요일을 인덱스로 하고, smoker를 열로 하며 통계를 냅니다.
'Python Library > Pandas' 카테고리의 다른 글
[Pandas - Python] 지금까지의 예시 + 코드에 대한 설명 (0) | 2022.06.16 |
---|---|
[Pandas - Python] Apply : General split-apply-combine (0) | 2022.06.16 |
[Pandas - Python] Data Aggregation - agg() (데이터 종합) (0) | 2022.06.16 |
[Pandas - Python] GroupBy Mechanics - groupby() (그룹으로 묶기) (0) | 2022.06.15 |
[Pandas - Python] Reshaping with Hierarchical Indexing - stack(), unstack() (계층적 인덱싱의 구조 변환) (0) | 2022.06.15 |