1. Pivot Table¶
엑셀 = pivot table 기능이 있다. 이것과 동일한 기능
Pandas에서는 pivot_table() 함수를 제공
피봇함수 역할?
df.pivot_table(
values=None,
index=None,
columns=None,
aggfunc='mean',
fill_value=None,
margins=False,
dropna=True,
margins_name='All',
observed=False,
)
In [1]:
import numpy as np
import pandas as pd
from pandas import Series, DataFrame
import matplotlib.pyplot as plt
In [2]:
data = {
"도시": ["서울", "서울", "서울", "부산", "부산", "부산", "인천", "인천"],
"연도": ["2015", "2010", "2005", "2015", "2010", "2005", "2015", "2010"],
"인구": [9904312, 9631482, 9762546, 3448737, 3393191, 3512547, 2890451, 263203],
"지역": ["수도권", "수도권", "수도권", "경상권", "경상권", "경상권", "수도권", "수도권"]
}
In [3]:
df1 = DataFrame(data )
df1
Out[3]:
도시 | 연도 | 인구 | 지역 | |
---|---|---|---|---|
0 | 서울 | 2015 | 9904312 | 수도권 |
1 | 서울 | 2010 | 9631482 | 수도권 |
2 | 서울 | 2005 | 9762546 | 수도권 |
3 | 부산 | 2015 | 3448737 | 경상권 |
4 | 부산 | 2010 | 3393191 | 경상권 |
5 | 부산 | 2005 | 3512547 | 경상권 |
6 | 인천 | 2015 | 2890451 | 수도권 |
7 | 인천 | 2010 | 263203 | 수도권 |
In [4]:
df1.pivot_table('인구','도시','연도') # 값 ,인덱스 , 컬럼
Out[4]:
연도 | 2005 | 2010 | 2015 |
---|---|---|---|
도시 | |||
부산 | 3512547.0 | 3393191.0 | 3448737.0 |
서울 | 9762546.0 | 9631482.0 | 9904312.0 |
인천 | NaN | 263203.0 | 2890451.0 |
In [5]:
df1.pivot_table(index='도시',values='인구', columns='연도')
Out[5]:
연도 | 2005 | 2010 | 2015 |
---|---|---|---|
도시 | |||
부산 | 3512547.0 | 3393191.0 | 3448737.0 |
서울 | 9762546.0 | 9631482.0 | 9904312.0 |
인천 | NaN | 263203.0 | 2890451.0 |
In [6]:
df1.pivot_table(index='도시',values='인구', columns='연도', margins=True) # All이란 이름으로 각 행과 열들의 평균값을 갖게된다.
Out[6]:
연도 | 2005 | 2010 | 2015 | All |
---|---|---|---|---|
도시 | ||||
부산 | 3512547.0 | 3393191.0 | 3448737.0 | 3.451492e+06 |
서울 | 9762546.0 | 9631482.0 | 9904312.0 | 9.766113e+06 |
인천 | NaN | 263203.0 | 2890451.0 | 1.576827e+06 |
All | 6637546.5 | 4429292.0 | 5414500.0 | 5.350809e+06 |
In [7]:
df1['인구'].mean()
Out[7]:
5350808.625
In [8]:
# groupby = pivot_table
df1.pivot_table(values='인구',index=['연도','도시']) # 연도별 도시의 인구가 나온다.
Out[8]:
인구 | ||
---|---|---|
연도 | 도시 | |
2005 | 부산 | 3512547 |
서울 | 9762546 | |
2010 | 부산 | 3393191 |
서울 | 9631482 | |
인천 | 263203 | |
2015 | 부산 | 3448737 |
서울 | 9904312 | |
인천 | 2890451 |
실전데이터 응용하기¶
In [9]:
tipdf = pd.read_csv('../data/tips.csv')
tipdf.head()
Out[9]:
total_bill | tip | sex | smoker | day | time | size | |
---|---|---|---|---|---|---|---|
0 | 16.99 | 1.01 | Female | No | Sun | Dinner | 2.0 |
1 | 10.34 | 1.66 | Male | No | Sun | Dinner | 3.0 |
2 | 21.01 | 3.50 | Male | No | Sun | Dinner | 3.0 |
3 | 23.68 | 3.31 | Male | No | Sun | Dinner | 2.0 |
4 | 24.59 | 3.61 | Female | No | Sun | Dinner | 4.0 |
해당 tips 데이터의 분석의 목표는 사실상 tip비율
식사대금 대비 팁의 비율이 어떤지 알수 있는 컬럼 하나를 더 추가해보자
tip_pct = tip/total
In [10]:
tipdf['tip_pct'] = tipdf['tip']/tipdf['total_bill']
tipdf.tail()
Out[10]:
total_bill | tip | sex | smoker | day | time | size | tip_pct | |
---|---|---|---|---|---|---|---|---|
240 | 27.18 | 2.00 | Female | Yes | Sat | Dinner | 2.0 | 0.073584 |
241 | 22.67 | 2.00 | Male | Yes | Sat | Dinner | 2.0 | 0.088222 |
242 | 17.82 | 1.75 | Male | No | Sat | Dinner | 2.0 | 0.098204 |
243 | 18.78 | 3.00 | Female | No | Thur | Dinner | 2.0 | 0.159744 |
244 | 25.34 | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
In [11]:
# 누락데이터 제거
tipdf.dropna(inplace=True)
tipdf.tail()
Out[11]:
total_bill | tip | sex | smoker | day | time | size | tip_pct | |
---|---|---|---|---|---|---|---|---|
239 | 29.03 | 5.92 | Male | No | Sat | Dinner | 3.0 | 0.203927 |
240 | 27.18 | 2.00 | Female | Yes | Sat | Dinner | 2.0 | 0.073584 |
241 | 22.67 | 2.00 | Male | Yes | Sat | Dinner | 2.0 | 0.088222 |
242 | 17.82 | 1.75 | Male | No | Sat | Dinner | 2.0 | 0.098204 |
243 | 18.78 | 3.00 | Female | No | Thur | Dinner | 2.0 | 0.159744 |
In [12]:
tipdf.describe() # 상세 설명
Out[12]:
total_bill | tip | size | tip_pct | |
---|---|---|---|---|
count | 244.000000 | 244.000000 | 244.000000 | 244.000000 |
mean | 19.785943 | 2.998279 | 2.569672 | 0.160803 |
std | 8.902412 | 1.383638 | 0.951100 | 0.061072 |
min | 3.070000 | 1.000000 | 1.000000 | 0.035638 |
25% | 13.347500 | 2.000000 | 2.000000 | 0.129127 |
50% | 17.795000 | 2.900000 | 2.000000 | 0.154770 |
75% | 24.127500 | 3.562500 | 3.000000 | 0.191475 |
max | 50.810000 | 10.000000 | 6.000000 | 0.710345 |
In [13]:
tipdf.info() # 상세 정보 내용
<class 'pandas.core.frame.DataFrame'>
Int64Index: 244 entries, 0 to 243
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 total_bill 244 non-null float64
1 tip 244 non-null float64
2 sex 244 non-null object
3 smoker 244 non-null object
4 day 244 non-null object
5 time 244 non-null object
6 size 244 non-null float64
7 tip_pct 244 non-null float64
dtypes: float64(4), object(4)
memory usage: 17.2+ KB
In [14]:
# 문제 1. tipdf에서 피봇함수를 사용해서 day로 세분화
tipdf.pivot_table(index='day',aggfunc='sum').round(2)
Out[14]:
size | tip | tip_pct | total_bill | |
---|---|---|---|---|
day | ||||
Fri | 40.0 | 51.96 | 3.23 | 325.88 |
Sat | 219.0 | 260.40 | 13.32 | 1778.40 |
Sun | 216.0 | 247.39 | 12.68 | 1627.16 |
Thur | 152.0 | 171.83 | 10.00 | 1096.33 |
In [15]:
# 문제 2. tipdf에서 sex smoker로 세분화.
tipdf.pivot_table(index=['sex','smoker']).round(2)
Out[15]:
size | tip | tip_pct | total_bill | ||
---|---|---|---|---|---|
sex | smoker | ||||
Female | No | 2.59 | 2.77 | 0.16 | 18.11 |
Yes | 2.24 | 2.93 | 0.18 | 17.98 | |
Male | No | 2.71 | 3.11 | 0.16 | 19.79 |
Yes | 2.50 | 3.05 | 0.15 | 22.28 |
In [16]:
'''
pivot_table() 함수 인자값 속성의 의미
index = 세분화, 그룹핑하는 기준
columns =
'''
tipdf.pivot_table(
values=['total_bill','tip'],
index = ['sex','day'],
columns=['smoker']
)
Out[16]:
tip | total_bill | ||||
---|---|---|---|---|---|
smoker | No | Yes | No | Yes | |
sex | day | ||||
Female | Fri | 3.125000 | 2.682857 | 19.365000 | 12.654286 |
Sat | 2.724615 | 2.868667 | 19.003846 | 20.266667 | |
Sun | 3.329286 | 3.500000 | 20.824286 | 16.540000 | |
Thur | 2.459600 | 2.990000 | 16.014400 | 19.218571 | |
Male | Fri | 2.500000 | 2.741250 | 17.475000 | 20.452500 |
Sat | 3.256563 | 2.879259 | 19.929063 | 21.837778 | |
Sun | 3.115349 | 3.521333 | 20.403256 | 26.141333 | |
Thur | 2.941500 | 3.058000 | 18.486500 | 19.171000 |
In [17]:
tipdf.pivot_table('tip','sex','smoker')
Out[17]:
smoker | No | Yes |
---|---|---|
sex | ||
Female | 2.773519 | 2.931515 |
Male | 3.113402 | 3.051167 |
In [18]:
# 문제 3. 성별에 따른 팁의 비율
#1. 피봇테이블 사용
tipdf.pivot_table(index='sex',values='tip_pct').round(3)*100
Out[18]:
tip_pct | |
---|---|
sex | |
Female | 16.6 |
Male | 15.8 |
In [19]:
#2. groupby 사용
tipdf.groupby(['sex'])[['tip']].agg('mean')
Out[19]:
tip | |
---|---|
sex | |
Female | 2.833448 |
Male | 3.089618 |
In [20]:
tipdf
Out[20]:
total_bill | tip | sex | smoker | day | time | size | tip_pct | |
---|---|---|---|---|---|---|---|---|
0 | 16.99 | 1.01 | Female | No | Sun | Dinner | 2.0 | 0.059447 |
1 | 10.34 | 1.66 | Male | No | Sun | Dinner | 3.0 | 0.160542 |
2 | 21.01 | 3.50 | Male | No | Sun | Dinner | 3.0 | 0.166587 |
3 | 23.68 | 3.31 | Male | No | Sun | Dinner | 2.0 | 0.139780 |
4 | 24.59 | 3.61 | Female | No | Sun | Dinner | 4.0 | 0.146808 |
... | ... | ... | ... | ... | ... | ... | ... | ... |
239 | 29.03 | 5.92 | Male | No | Sat | Dinner | 3.0 | 0.203927 |
240 | 27.18 | 2.00 | Female | Yes | Sat | Dinner | 2.0 | 0.073584 |
241 | 22.67 | 2.00 | Male | Yes | Sat | Dinner | 2.0 | 0.088222 |
242 | 17.82 | 1.75 | Male | No | Sat | Dinner | 2.0 | 0.098204 |
243 | 18.78 | 3.00 | Female | No | Thur | Dinner | 2.0 | 0.159744 |
244 rows × 8 columns
In [21]:
# 문제 4. 그룹바이로... 각 그룹에서 가장 많은 팁과 가장 적은 팁의 차이를 디스플레이 하세요(단, 사용자정의 함수를 지정할때 max_min_tip 으로 정의하세요)
def max_min_tip(x):
return x.max()-x.min()
tipdf.groupby(['sex','smoker'])[['tip']].agg(max_min_tip)
Out[21]:
tip | ||
---|---|---|
sex | smoker | |
Female | No | 4.20 |
Yes | 5.50 | |
Male | No | 7.75 |
Yes | 9.00 |
'workSpace > PYTHON' 카테고리의 다른 글
[ML][DL] 전반적인 이해도 및 로직 설명, 자료 (0) | 2021.01.18 |
---|---|
[Pandas] 판다스 기초 상식 정리 및 함수 응용 3 - 네이버 영화 평점 분석 (0) | 2021.01.14 |
[Pandas] 판다스 기초 상식 및 함수 정리 3 - groupby (0) | 2021.01.14 |
[Pandas] 판다스 기초 상식 정리 및 함수 응용 2 - 서울시 구별 CCTV 현황 분석하기 (0) | 2021.01.13 |
[Pandas] 판다스 기초 상식 정리 및 함수 응용 1 - 서울시 기간별 시간평균 대기환경 정보 데이터 분석 (0) | 2021.01.13 |