본문 바로가기
pandas

Groupby와 Pivot table

by 자동매매 2023. 12. 12.

참조 :

한 권으로 끝내는 <판다스 노트>

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

댓글