DataFrame.groupby(by=None, axis=0, level=None, as_index=Ture, sort=True, group_keys=True, squeeze=NoDefault.no_default, observed=false, dropna=True)
데이터를 그룹화하여 연산을 수항하는 메서드
(데이터를 의미 있는 단위로 나눠서 요약·비교·해석하는 도구)
SQL의 GROUP BY
#1
idx = ['A','A','B','B','B','C','C','C','D','D','D','D','E','E','E']
col = ['col1','col2','col3']
data = np.random.randint(0,9,(15,3))
df = pd.DataFrame(data=data, index=idx, columns=col).reset_index()
print(df)
index col1 col2 col3
0 A 6 5 4
1 A 6 7 6
2 B 1 0 8
3 B 5 0 2
4 B 6 6 3
5 C 8 0 1
6 C 2 8 2
7 C 8 7 4
8 D 0 4 0
9 D 5 8 8
10 D 8 7 6
11 D 6 3 8
12 E 7 2 7
13 E 7 5 0
14 E 7 2 7
#2
print(df.groupby('index'))
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x000001D9CB952270>
#3
print(df.groupby('index').mean())
col1 col2 col3
index
A 6.00 6.0 5.000000
B 4.00 2.0 4.333333
C 6.00 5.0 2.333333
D 4.75 5.5 5.500000
E 7.00 3.0 4.666667
인자로 가능한 것들:
'mean'
'sum'
'count'
'min'
'max'
'std'
'var'
'nunique'
'first', 'last'
-> 내장 집계 함수 이름 문자열
print(df.groupby('index').agg(["min","max"]))
col1 col2 col3
min max min max min max
index
A 6 6 5 7 4 6
B 1 6 0 6 2 8
C 2 8 0 8 1 4
D 0 8 3 8 0 8
E 7 7 2 5 0 7
가장 큰 이유는 성능:
agg
apply
데이터 커질수록:
agg -> 선형 증가
apply -> 급격히 느려짐
실무에서 apply 남용 = 성능 병목 1순위
apply 결과를 어떻게 합칠지에 관여
| 상황 | group_keys 영향 |
|---|---|
sum, mean, count | ❌ 없음 |
agg (표준 집계) | ❌ 없음 |
apply (row 반환) | ✅ 있음 |
apply (DataFrame 반환) | ✅ 매우 중요 |
df.groupby('index', group_keys=False).apply(lambda x: x.head(1))
Categorical 객체를 생성할 때, 그룹화할 열에 있는 값이 아닌 값을 포함하게 되면, 그룹화 할 때 해당 값을 표시할지 여부 선택
df_cat = pd.Categorical(df['index'], categories=['A', 'B', 'C', 'D', 'E', 'F'])
# index에 대해서 카테고리를 일부러 추가적으로 'F'를 넣어 설정 - F는 기존 df에 없음
print(df_cat)
print(df['col1'].groupby(df_cat, observed=Ture).count())
A 2
B 3
C 3
D 4
E 3
Name: col1, dtype: int64
print(df['col1'].groupby(df_cat, observed=False).count()) #observed개 False 인 경우에는 지정한대로 F까지 표시
A 2
B 3
C 3
D 4
E 3
F 0
Name: col1, dtype: int64
특정 열을 지정하여 groupby 할 경우 해당 열이 인덱스가 되는데, as_index=False로 하여 기존 인덱스 유지 가능
print(df.groupby(['index'], as_index=False).sum())
index col1 col2 col3
0 A 5 14 6
1 B 17 8 15
2 C 15 8 17
3 D 20 11 20
4 E 4 12 15
print(df.groupby(['index'], as_index=True).sum())
col1 col2 col3
index
A 5 14 6
B 17 8 15
C 15 8 17
D 20 11 20
E 4 12 15
NaN이 데이터에 포함되는 경우 포함할지 하지 않을지 정할 수 있음
df.loc[6,'index'] = np.nan
print(df)
index col1 col2 col3
0 A 1 8 1
1 A 4 6 5
2 B 8 3 7
3 B 6 2 4
4 B 3 3 4
5 C 5 3 8
6 NaN 4 4 5
7 C 6 1 4
8 D 5 2 2
9 D 7 0 6
10 D 7 8 8
11 D 1 1 4
12 E 0 3 8
13 E 4 5 0
14 E 0 4 7
print(df.groupby('index').sum())
col1 col2 col3
index
A 5 14 6
B 17 8 15
C 11 4 12
D 20 11 20
E 4 12 15
print(df.groupby('index', dropna=False).sum())
col1 col2 col3
index
A 5 14 6
B 17 8 15
C 11 4 12
D 20 11 20
E 4 12 15
NaN 4 4 5
level을 숫자나 str 형태로 지정해주어 groupby 실행
print(df.groupby(level=1).sum()) # level int로 지정
print(df.groupby{[lv1], [lv0]}.sum())