Post

[사전학습] 2.4 데이터 그룹핑

데이터 그룹핑

groupby 함수

1
2
import numpy as np
import pandas as pd
1
2
3
4
5
6
7
8
df = pd.DataFrame({
    '학과' : ['수학', '화학', '수학', '화학', '수학'],
    '이름' : ['로버트', '앤드류', '유진', '제이슨', '제이크'],
    '학년' : [1, 2, 3, 2, 3],
    '학점' : [1.5, 2.7, 3.5, 1.9, 4.0]
})

df
학과이름학년학점
0수학로버트11.5
1화학앤드류22.7
2수학유진33.5
3화학제이슨21.9
4수학제이크34.0
1
df_dept = df.groupby('학과')
1
df_dept
1
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x00000172508FD448>
1
df_dept.describe()
학년학점
countmeanstdmin25%50%75%maxcountmeanstdmin25%50%75%max
학과
수학3.02.3333331.1547011.02.03.03.03.03.03.01.3228761.52.53.53.754.0
화학2.02.0000000.0000002.02.02.02.02.02.02.30.5656851.92.12.32.502.7
1
df_dept.count()
이름학년학점
학과
수학333
화학222

1단계 그룹핑

1
2
3
# Series에 대한 1단계 그룹핑
dept = df['학점'].groupby(df['학과'])
dept
1
<pandas.core.groupby.generic.SeriesGroupBy object at 0x000001725093D588>
1
dept.mean()
1
2
3
4
학과
수학    3.0
화학    2.3
Name: 학점, dtype: float64
1
dept.std()
1
2
3
4
학과
수학    1.322876
화학    0.565685
Name: 학점, dtype: float64
1
group_size = dept.size()
1
group_size
1
2
3
4
학과
수학    3
화학    2
Name: 학점, dtype: int64
1
2
3
# 수학과 인원의 데이터만 따로 출력
math = dept.get_group('수학')
math
1
2
3
4
0    1.5
2    3.5
4    4.0
Name: 학점, dtype: float64

이처럼 GropuBy 객체의 그룹연산 메서드는 다양하다. 자주 사용되는 메서드는 아래와 같다.

  • mean, median, min, max, std : 그룹 데이터의 평균, 중앙, 최소, 최대, 표준편차 값
  • size, count : 그룹 데이터의 갯수
  • describe : 위 집계 연산과 1사분위, 3사분위값을 포함하여 데이터프레임으로 나타냄
  • sum, quantile : 그룹 데이터의 합계, 사분위수
  • agg, aggregate, apply : 원하는 그룹연산 함수를 만들어 agg, aggregate, apply 에 전달하여 적용할 수 있음

2단계 그룹핑

1
2
dept = df.groupby([df['학과'], df['학년']])
dept
1
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000017250956DC8>
1
dept.describe()
학점
countmeanstdmin25%50%75%max
학과학년
수학11.01.50NaN1.51.5001.501.5001.5
32.03.750.3535533.53.6253.753.8754.0
화학22.02.300.5656851.92.1002.302.5002.7
1
display(dept.mean())
학점
학과학년
수학11.50
33.75
화학22.30
1
2
3
4
5
6
7
8
9
10
df2 = pd.DataFrame({
    '학과' : ['화학', '수학', '화학', '수학'],
    '이름' : ['앤디', '제니', '엘리스', '멜리샤'],
    '학년' : [1, 2, 3, 2],
    '학점' : [3, 4.2, 3.1, 4.5]
})

concat_df = pd.concat([df, df2], axis=0)
concat_df.reset_index(inplace=True, drop=True)
display(concat_df)
학과이름학년학점
0수학로버트11.5
1화학앤드류22.7
2수학유진33.5
3화학제이슨21.9
4수학제이크34.0
5화학앤디13.0
6수학제니24.2
7화학엘리스33.1
8수학멜리샤24.5
1
dept_and_year = concat_df.groupby([concat_df['학과'], concat_df['학년']])
1
dept_and_year.describe()
학점
countmeanstdmin25%50%75%max
학과학년
수학11.01.50NaN1.51.5001.501.5001.5
22.04.350.2121324.24.2754.354.4254.5
32.03.750.3535533.53.6253.753.8754.0
화학11.03.00NaN3.03.0003.003.0003.0
22.02.300.5656851.92.1002.302.5002.7
31.03.10NaN3.13.1003.103.1003.1
1
dept_and_year.mean()
학점
학과학년
수학11.50
24.35
33.75
화학13.00
22.30
33.10
1
dept_and_year.mean().index
1
2
3
4
5
6
7
MultiIndex([('수학', 1),
            ('수학', 2),
            ('수학', 3),
            ('화학', 1),
            ('화학', 2),
            ('화학', 3)],
           names=['학과', '학년'])

apply 함수

1
2
def top3_dept_scorer(df):
    return df.sort_values(by='학점', ascending=False)[:3] # 학점 상위 3명 return
1
dept = concat_df.groupby('학과')
1
dept.apply(top3_dept_scorer)
학과이름학년학점
학과
수학8수학멜리샤24.5
6수학제니24.2
4수학제이크34.0
화학7화학엘리스33.1
5화학앤디13.0
1화학앤드류22.7
1
2
def top2_scorer(series):
    return series.sort_values(ascending=False)[:2]
1
dept['학점'].apply(top2_scorer)
1
2
3
4
5
6
학과   
수학  8    4.5
    6    4.2
화학  7    3.1
    5    3.0
Name: 학점, dtype: float64
1
pd.DataFrame(dept['학점'].apply(top2_scorer))
학점
학과
수학84.5
64.2
화학73.1
53.0

lambda 식 활용

1
2
3
4
df = pd.DataFrame({
    'key' : ['A', 'B', 'B', 'C', 'A', 'C', 'A', 'B', 'C', 'A'],
    'data' : [1, 2, 2, 1, 3, 8, 2, 5, 3, 6]
})
1
df.groupby('key').apply(lambda x: x.sort_values(by='data'))
keydata
key
A0A1
6A2
4A3
9A6
B1B2
2B2
7B5
C3C1
8C3
5C8
1
2
dept = concat_df.groupby('학과')
dept
1
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000017252891C48>
1
dept.apply(lambda x: x.sort_values(by='학점', ascending=False)[:3])
학과이름학년학점
학과
수학8수학멜리샤24.5
6수학제니24.2
4수학제이크34.0
화학7화학엘리스33.1
5화학앤디13.0
1화학앤드류22.7

groupby와 재귀함수

1
2
3
for dept, group in concat_df.groupby(concat_df['학과']):
    print('학과 : {}'.format(dept))
    display(group)
1
학과 : 수학
학과이름학년학점
0수학로버트11.5
2수학유진33.5
4수학제이크34.0
6수학제니24.2
8수학멜리샤24.5
1
학과 : 화학
학과이름학년학점
1화학앤드류22.7
3화학제이슨21.9
5화학앤디13.0
7화학엘리스33.1
1
2
3
4
5
for (dept, year), group in concat_df.groupby([concat_df['학과'], concat_df['학년']]):
    print('-'*25)
    print('학과 : ', dept)
    print('학년 : ', year)
    display(group)
1
2
3
-------------------------
학과 :  수학
학년 :  1
학과이름학년학점
0수학로버트11.5
1
2
3
-------------------------
학과 :  수학
학년 :  2
학과이름학년학점
6수학제니24.2
8수학멜리샤24.5
1
2
3
-------------------------
학과 :  수학
학년 :  3
학과이름학년학점
2수학유진33.5
4수학제이크34.0
1
2
3
-------------------------
학과 :  화학
학년 :  1
학과이름학년학점
5화학앤디13.0
1
2
3
-------------------------
학과 :  화학
학년 :  2
학과이름학년학점
1화학앤드류22.7
3화학제이슨21.9
1
2
3
-------------------------
학과 :  화학
학년 :  3
학과이름학년학점
7화학엘리스33.1
1
This post is licensed under CC BY 4.0 by the author.

[사전학습] 2.3 데이터 합치기

[사전학습] 2.5 시계열 기초