참조 :
한 권으로 끝내는 <판다스 노트>
https://e-koreatech.step.or.kr/
groupby()는 데이터를 피봇팅하여 통계량을 볼 수 있도록 도와주는 메서드이면서, 데이터를 특정 조건에 맞게 전처리해 줄 때 용이합니다.
pivot_table()은 데이터를 특정 조건에 따라 행(row)과 열(column)을 기준으로 데이터를 펼쳐서 그에 대한 통계량을 볼 때 활용합니다.
from IPython.display import Image
import numpy as np
import pandas as pd
import seaborn as sns
df = sns.load_dataset('titanic')
df.head()
1. apply() - 함수를 적용
apply()는 데이터 전처리시 굉장히 많이 활용하는 기능입니다.
좀 더 복잡한 logic( 일반함수, lambda 함수)을 컬럼 혹은 DataFrame에 적용하고자 할 때 사용합니다.
1) 함수(function) 정의 후 특정 컬럼에 적용
def transform_who(x):
if x == 'man':
return '남자'
elif x == 'woman':
return '여자'
else:
return '아이'
df['who'].apply(transform_who)
0 남자
1 여자
2 여자
3 여자
4 남자
..
886 남자
887 여자
888 여자
889 남자
890 남자
Name: who, Length: 891, dtype: object
2) 함수(function) 정의 후 DataFrame에 적용
def transform_who(x):
return x['fare'] / x['age']
df.apply(transform_who, axis=1)
0 0.329545
1 1.875876
2 0.304808
3 1.517143
4 0.230000
...
886 0.481481
887 1.578947
888 NaN
889 1.153846
890 0.242188
Length: 891, dtype: float64
# lambda함수 적용
df['survived'].apply(lambda x: '생존' if x == 1 else '사망')
0 사망
1 생존
2 생존
3 생존
4 사망
..
886 사망
887 생존
888 사망
889 생존
890 사망
Name: survived, Length: 891, dtype: object
2. Groupby()
데이터를 특정 기준으로 그룹핑할 때 활용합니다. 엑셀의 피봇테이블과 유사합니다.
타이타닉 호의 생존자와 사망자를 성별 기준으로 그룹핑하여 평균을 살펴보겠습니다.
groupby()를 사용할 때는 반드시 aggregate 하는 통계함수와 일반적으로 같이 적용합니다.
df.groupby('sex').mean()
survived pclass age sibsp parch fare adult_male alone
sex
female 0.74 2.16 27.92 0.69 0.65 44.48 0.00 0.40
male 0.19 2.39 30.73 0.43 0.24 25.52 0.93 0.71
1) 2개 이상의 컬럼으로 그룹
2개 이상의 컬럼으로 그룹핑할 때도 list로 묶어서 지정하면 됩니다.
# 성별, 좌석등급 별 통계
df.groupby(['sex', 'pclass']).mean()
survived | age | sibsp | parch | fare | adult_male | alone | ||
sex | pclass | |||||||
female | 1 | 0.97 | 34.61 | 0.55 | 0.46 | 106.13 | 0 | 0.36 |
2 | 0.92 | 28.72 | 0.49 | 0.61 | 21.97 | 0 | 0.42 | |
3 | 0.5 | 21.75 | 0.9 | 0.8 | 16.12 | 0 | 0.42 | |
male | 1 | 0.37 | 41.28 | 0.31 | 0.28 | 67.23 | 0.98 | 0.61 |
2 | 0.16 | 30.74 | 0.34 | 0.22 | 19.74 | 0.92 | 0.67 | |
3 | 0.14 | 26.51 | 0.5 | 0.22 | 12.66 | 0.92 | 0.76 |
2) 1개의 특정 컬럼에 대한 결과 도출
만약 survived컬럼에 대한 결과만 도출하고 싶다면 컬럼을 맨 끝에 지정합니다.
# 성별, 좌석등급 별 통계
df.groupby(['sex', 'pclass'])['survived'].mean()
# 동일기능
df.groupby(['sex', 'pclass']).mean()['survived']
sex pclass
female 1 0.968085
2 0.921053
3 0.500000
male 1 0.368852
2 0.157407
3 0.135447
Name: survived, dtype: float64
# 출력을 보기좋게 하기
pd.DataFrame()으로 감싸주거나, survived 컬럼을 []로 한 번 더 감싸주면 됩니다.
# DataFrame으로 출력
pd.DataFrame(df.groupby(['sex', 'pclass'])['survived'].mean())
df.groupby(['sex', 'pclass'])[['survived']].mean()
survived | ||
sex | pclass | |
female | 1 | 0.97 |
2 | 0.92 | |
3 | 0.5 | |
male | 1 | 0.37 |
2 | 0.16 | |
3 | 0.14 |
3) 다중 컬럼에 대한 결과 도출
끝에 단일 컬럼이 아닌 여러 개의 컬럼을 지정합니다.
# 성별, 좌석등급 별 통계
df.groupby(['sex', 'pclass'])[['survived', 'age']].mean()
survived | age | ||
sex | pclass | ||
female | 1 | 0.97 | 34.61 |
2 | 0.92 | 28.72 | |
3 | 0.5 | 21.75 | |
male | 1 | 0.37 | 41.28 |
2 | 0.16 | 30.74 | |
3 | 0.14 | 26.51 |
4) 다중 통계 함수 적용
여러 가지의 통계 값을 적용할 때는 agg()를 사용합니다.
# 성별, 좌석등급 별 통계
df.groupby(['sex', 'pclass'])[['survived', 'age']].agg(['mean', 'sum'])
survived | age | ||||
mean | sum | mean | sum | ||
sex | pclass | ||||
female | 1 | 0.97 | 91 | 34.61 | 2942 |
2 | 0.92 | 70 | 28.72 | 2125.5 | |
3 | 0.5 | 72 | 21.75 | 2218.5 | |
male | 1 | 0.37 | 45 | 41.28 | 4169.42 |
2 | 0.16 | 17 | 30.74 | 3043.33 | |
3 | 0.14 | 47 | 26.51 | 6706.42 |
3. reset_index(): 인덱스 초기화
reset_index(): 그룹핑된 데이터프레임의 index를 초기화하여 새로운 데이터프레임을 생성합니다.
# index 초기화
df.groupby(['sex', 'pclass'])['survived'].mean().reset_index()
sex | pclass | survived | |
0 | female | 1 | 0.97 |
1 | female | 2 | 0.92 |
2 | female | 3 | 0.5 |
3 | male | 1 | 0.37 |
4 | male | 2 | 0.16 |
5 | male | 3 | 0.14 |
4. Pivot_table()
피벗테이블은 엑셀의 피벗과 동작이 유사하며, groupby()와도 동작이 유사합니다.
기본 동작 원리는 index, columns, values를 지정하여 피벗합니다.
1) 1개 그룹에 대한 단일 컬럼 결과
# index에 그룹을 표기
df.pivot_table(index='who', values='survived')
survived | |
who | |
child | 0.59 |
man | 0.16 |
woman | 0.76 |
# columns에 그룹을 표기
df.pivot_table(columns='who', values='survived')
who | child | man | woman |
survived | 0.59 | 0.16 | 0.76 |
2) 다중 그룹에 대한 단일 컬럼 결과
df.pivot_table(index=['who', 'pclass'], values='survived')
survived | ||
who | pclass | |
child | 1 | 0.83 |
2 | 1 | |
3 | 0.43 | |
man | 1 | 0.35 |
2 | 0.08 | |
3 | 0.12 | |
woman | 1 | 0.98 |
2 | 0.91 | |
3 | 0.49 |
3) index에 컬럼을 중첩하지 않고 행과 열로 펼친 결과
df.pivot_table(index='who', columns='pclass', values='survived')
pclass | 1 | 2 | 3 |
who | |||
child | 0.83 | 1 | 0.43 |
man | 0.35 | 0.08 | 0.12 |
woman | 0.98 | 0.91 | 0.49 |
4) 다중 통계함수 적용
df.pivot_table(index='who', columns='pclass', values='survived', aggfunc=['sum', 'mean'])
sum | mean | |||||
pclass | 1 | 2 | 3 | 1 | 2 | 3 |
who | ||||||
child | 5 | 19 | 25 | 0.833333 | 1 | 0.431034 |
man | 42 | 8 | 38 | 0.352941 | 0.080808 | 0.119122 |
woman | 89 | 60 | 56 | 0.978022 | 0.909091 | 0.491228 |
'pandas' 카테고리의 다른 글
matplotlib (0) | 2023.12.14 |
---|---|
연결(Concat)과 병합(Merge) (0) | 2023.12.12 |
데이터 전처리, 추가, 삭제, 변환 (0) | 2023.12.12 |
복사와 결측치 (0) | 2023.12.12 |
통계 (0) | 2023.12.11 |
댓글