[사전학습] 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 | 수학 | 로버트 | 1 | 1.5 |
1 | 화학 | 앤드류 | 2 | 2.7 |
2 | 수학 | 유진 | 3 | 3.5 |
3 | 화학 | 제이슨 | 2 | 1.9 |
4 | 수학 | 제이크 | 3 | 4.0 |
1
df_dept = df.groupby('학과')
1
df_dept
1
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x00000172508FD448>
1
df_dept.describe()
학년 | 학점 | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
count | mean | std | min | 25% | 50% | 75% | max | count | mean | std | min | 25% | 50% | 75% | max | |
학과 | ||||||||||||||||
수학 | 3.0 | 2.333333 | 1.154701 | 1.0 | 2.0 | 3.0 | 3.0 | 3.0 | 3.0 | 3.0 | 1.322876 | 1.5 | 2.5 | 3.5 | 3.75 | 4.0 |
화학 | 2.0 | 2.000000 | 0.000000 | 2.0 | 2.0 | 2.0 | 2.0 | 2.0 | 2.0 | 2.3 | 0.565685 | 1.9 | 2.1 | 2.3 | 2.50 | 2.7 |
1
df_dept.count()
이름 | 학년 | 학점 | |
---|---|---|---|
학과 | |||
수학 | 3 | 3 | 3 |
화학 | 2 | 2 | 2 |
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()
학점 | |||||||||
---|---|---|---|---|---|---|---|---|---|
count | mean | std | min | 25% | 50% | 75% | max | ||
학과 | 학년 | ||||||||
수학 | 1 | 1.0 | 1.50 | NaN | 1.5 | 1.500 | 1.50 | 1.500 | 1.5 |
3 | 2.0 | 3.75 | 0.353553 | 3.5 | 3.625 | 3.75 | 3.875 | 4.0 | |
화학 | 2 | 2.0 | 2.30 | 0.565685 | 1.9 | 2.100 | 2.30 | 2.500 | 2.7 |
1
display(dept.mean())
학점 | ||
---|---|---|
학과 | 학년 | |
수학 | 1 | 1.50 |
3 | 3.75 | |
화학 | 2 | 2.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 | 수학 | 로버트 | 1 | 1.5 |
1 | 화학 | 앤드류 | 2 | 2.7 |
2 | 수학 | 유진 | 3 | 3.5 |
3 | 화학 | 제이슨 | 2 | 1.9 |
4 | 수학 | 제이크 | 3 | 4.0 |
5 | 화학 | 앤디 | 1 | 3.0 |
6 | 수학 | 제니 | 2 | 4.2 |
7 | 화학 | 엘리스 | 3 | 3.1 |
8 | 수학 | 멜리샤 | 2 | 4.5 |
1
dept_and_year = concat_df.groupby([concat_df['학과'], concat_df['학년']])
1
dept_and_year.describe()
학점 | |||||||||
---|---|---|---|---|---|---|---|---|---|
count | mean | std | min | 25% | 50% | 75% | max | ||
학과 | 학년 | ||||||||
수학 | 1 | 1.0 | 1.50 | NaN | 1.5 | 1.500 | 1.50 | 1.500 | 1.5 |
2 | 2.0 | 4.35 | 0.212132 | 4.2 | 4.275 | 4.35 | 4.425 | 4.5 | |
3 | 2.0 | 3.75 | 0.353553 | 3.5 | 3.625 | 3.75 | 3.875 | 4.0 | |
화학 | 1 | 1.0 | 3.00 | NaN | 3.0 | 3.000 | 3.00 | 3.000 | 3.0 |
2 | 2.0 | 2.30 | 0.565685 | 1.9 | 2.100 | 2.30 | 2.500 | 2.7 | |
3 | 1.0 | 3.10 | NaN | 3.1 | 3.100 | 3.10 | 3.100 | 3.1 |
1
dept_and_year.mean()
학점 | ||
---|---|---|
학과 | 학년 | |
수학 | 1 | 1.50 |
2 | 4.35 | |
3 | 3.75 | |
화학 | 1 | 3.00 |
2 | 2.30 | |
3 | 3.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 | 수학 | 멜리샤 | 2 | 4.5 |
6 | 수학 | 제니 | 2 | 4.2 | |
4 | 수학 | 제이크 | 3 | 4.0 | |
화학 | 7 | 화학 | 엘리스 | 3 | 3.1 |
5 | 화학 | 앤디 | 1 | 3.0 | |
1 | 화학 | 앤드류 | 2 | 2.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))
학점 | ||
---|---|---|
학과 | ||
수학 | 8 | 4.5 |
6 | 4.2 | |
화학 | 7 | 3.1 |
5 | 3.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'))
key | data | ||
---|---|---|---|
key | |||
A | 0 | A | 1 |
6 | A | 2 | |
4 | A | 3 | |
9 | A | 6 | |
B | 1 | B | 2 |
2 | B | 2 | |
7 | B | 5 | |
C | 3 | C | 1 |
8 | C | 3 | |
5 | C | 8 |
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 | 수학 | 멜리샤 | 2 | 4.5 |
6 | 수학 | 제니 | 2 | 4.2 | |
4 | 수학 | 제이크 | 3 | 4.0 | |
화학 | 7 | 화학 | 엘리스 | 3 | 3.1 |
5 | 화학 | 앤디 | 1 | 3.0 | |
1 | 화학 | 앤드류 | 2 | 2.7 |
groupby
와 재귀함수
1
2
3
for dept, group in concat_df.groupby(concat_df['학과']):
print('학과 : {}'.format(dept))
display(group)
1
학과 : 수학
학과 | 이름 | 학년 | 학점 | |
---|---|---|---|---|
0 | 수학 | 로버트 | 1 | 1.5 |
2 | 수학 | 유진 | 3 | 3.5 |
4 | 수학 | 제이크 | 3 | 4.0 |
6 | 수학 | 제니 | 2 | 4.2 |
8 | 수학 | 멜리샤 | 2 | 4.5 |
1
학과 : 화학
학과 | 이름 | 학년 | 학점 | |
---|---|---|---|---|
1 | 화학 | 앤드류 | 2 | 2.7 |
3 | 화학 | 제이슨 | 2 | 1.9 |
5 | 화학 | 앤디 | 1 | 3.0 |
7 | 화학 | 엘리스 | 3 | 3.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 | 수학 | 로버트 | 1 | 1.5 |
1
2
3
-------------------------
학과 : 수학
학년 : 2
학과 | 이름 | 학년 | 학점 | |
---|---|---|---|---|
6 | 수학 | 제니 | 2 | 4.2 |
8 | 수학 | 멜리샤 | 2 | 4.5 |
1
2
3
-------------------------
학과 : 수학
학년 : 3
학과 | 이름 | 학년 | 학점 | |
---|---|---|---|---|
2 | 수학 | 유진 | 3 | 3.5 |
4 | 수학 | 제이크 | 3 | 4.0 |
1
2
3
-------------------------
학과 : 화학
학년 : 1
학과 | 이름 | 학년 | 학점 | |
---|---|---|---|---|
5 | 화학 | 앤디 | 1 | 3.0 |
1
2
3
-------------------------
학과 : 화학
학년 : 2
학과 | 이름 | 학년 | 학점 | |
---|---|---|---|---|
1 | 화학 | 앤드류 | 2 | 2.7 |
3 | 화학 | 제이슨 | 2 | 1.9 |
1
2
3
-------------------------
학과 : 화학
학년 : 3
학과 | 이름 | 학년 | 학점 | |
---|---|---|---|---|
7 | 화학 | 엘리스 | 3 | 3.1 |
1
This post is licensed under CC BY 4.0 by the author.