그룹분석
키가 지정하는 조건에 맞는 데이터가 하나 이상으로 데이터 그룹을 이루는 경우, 그룹분석을 사용해 그룹의 특성을 확인해야 한다. 그룹의 특성은 미리 지정한 연산을 이용해 계산한 그룹의 대푯값으로 한다. Pandas에서는 다음과 같은 방식으로 그룹분석을 수행한다.
1. 분석할 시리즈나 데이터 프레임에 groupby 함수를 실행하여 그룹화를 한다.
2. 그룹화한 데이터에 그룹연산을 수행한다.
groupby
데이터를 그룹 별로 분류하는 함수로 열 또는 열의 리스트, 행 인덱스를 매개변수로 전달한다.
groupby 함수는 그룹 데이터를 나타내는 GroupBy 클래스 객체를 반환한다. GroupBy 객체는 그룹변로 연산할 수 있는 그룹연산 함수를 제공한다.
그룹연산 함수
자주 사용하는 그룹연산 함수는 다음과 같다.
- size, count : 그룹 데이터의 개수
- mean, median, min, max : 그룹 데이터의 평균, 중앙값, 최소, 최대
- sum, prod, std, var, quantile : 그룹 테이터의 합계, 곱, 표준편차, 분산, 사분위수
- first, last : 그룹 데이터 중 첫번째 데이터와 마지막 데이터
- agg, aggregate : 사용자 정의 그룹 연산 함수를 생성하여 전달하거나 여러 그룹 연산을 동시에 실행시킬 때 함수 이름을 문자열 리스트로 전달한다.
def peak_to_peak_ratio(x):
return x.max() / x.min()
iris.groupby(iris.species).agg(peak_to_peak_ratio)
# 실행 결과
sepal_length sepal_width petal_length petal_width
species
setosa 1.348837 1.913043 1.900000 6.000000
versicolor 1.428571 1.700000 1.700000 1.800000
virginica 1.612245 1.727273 1.533333 1.785714
- describe : 다양한 기술 통계 값을 포함한 데이터프레임을 반환한다.
iris.groupby(iris.species).describe().T
# 실행 결과
species setosa versicolor virginica
sepal_length count 50.000000 50.000000 50.000000
mean 5.006000 5.936000 6.588000
std 0.352490 0.516171 0.635880
min 4.300000 4.900000 4.900000
25% 4.800000 5.600000 6.225000
50% 5.000000 5.900000 6.500000
75% 5.200000 6.300000 6.900000
max 5.800000 7.000000 7.900000
sepal_width count 50.000000 50.000000 50.000000
mean 3.428000 2.770000 2.974000
std 0.379064 0.313798 0.322497
min 2.300000 2.000000 2.200000
25% 3.200000 2.525000 2.800000
50% 3.400000 2.800000 3.000000
75% 3.675000 3.000000 3.175000
max 4.400000 3.400000 3.800000
petal_length count 50.000000 50.000000 50.000000
mean 1.462000 4.260000 5.552000
std 0.173664 0.469911 0.551895
min 1.000000 3.000000 4.500000
25% 1.400000 4.000000 5.100000
50% 1.500000 4.350000 5.550000
75% 1.575000 4.600000 5.875000
max 1.900000 5.100000 6.900000
...
min 0.100000 1.000000 1.400000
25% 0.200000 1.200000 1.800000
50% 0.200000 1.300000 2.000000
75% 0.300000 1.500000 2.300000
max 0.600000 1.800000 2.500000
- apply : 원하는 그룹 연산이 없을 때 사용한다.
def top3_petal_length(df):
return df.sort_values(by="petal_length", ascending=False)[:3]
iris.groupby(iris.species).apply(top3_petal_length)
# 실행 결과
sepal_length sepal_width petal_length petal_width species
species
setosa 24 4.8 3.4 1.9 0.2 setosa
44 5.1 3.8 1.9 0.4 setosa
23 5.1 3.3 1.7 0.5 setosa
versicolor 83 6.0 2.7 5.1 1.6 versicolor
77 6.7 3.0 5.0 1.7 versicolor
72 6.3 2.5 4.9 1.5 versicolor
virginica 118 7.7 2.6 6.9 2.3 virginica
117 7.7 3.8 6.7 2.2 virginica
122 7.7 2.8 6.7 2.0 virginica
- transform : 그룹 별 계산을 통해 데이터 자체를 변형한다.
def q3cut(s):
return pd.qcut(s, 3, labels=["소", "중", "대"]).astype(str)
iris["petal_length_class"] = iris.groupby(iris.species).petal_length.transform(q3cut)
iris[["petal_length", "petal_length_class"]].tail(10)
# 실행 결과
petal_length petal_length_class
140 5.6 중
141 5.1 소
142 5.1 소
143 5.9 대
144 5.7 중
145 5.2 소
146 5.0 소
147 5.2 소
148 5.4 중
149 5.1 소
예시
아래와 같은 데이터가 있다고 하자.
df2 = pd.DataFrame({
'key1': ['A', 'A', 'B', 'B', 'A'],
'key2': ['one', 'two', 'one', 'two', 'one'],
'data1': [1, 2, 3, 4, 5],
'data2': [10, 20, 30, 40, 50]
})
df2
# 실행 결과
key1 key2 data1 data2
0 A one 1 10
1 A two 2 20
2 B one 3 30
3 B two 4 40
4 A one 5 50
위 데이터의 key1의 값에 따른 data1의 평균은 다음과 같이 구할 수 있다.
# 데이터 그룹화
g = df2.groupby(df2.key1)
g.groups
g.mean(numeric_only=True)
## 실행 결과
{'A': [0, 1, 4], 'B': [2, 3]}
data1 data2
key1
A 2.666667 26.666667
B 3.500000 35.000000
GroupBy 객체는 groups 속성을 이용해 그룹화된 데이터를 조회할 수 있다. 또한 인덱싱을 이용해 특정 컬럼만 연산할 수도 있다.
df2.groupby(df2.key2)['data2'].sum(numeric_only=True)
# 실행 결과
key2
one 90
two 60
Name: data2, dtype: int64
groupby 함수에 키 리스트를 전달하면 복합 키에 따른 groupby 연산을 수행할 수 있다.
df2.data1.groupby([df2.key1, df2.key2]).first()
# 실행 결과
key1 key2
A one 1
two 2
B one 3
two 4
Name: data1, dtype: int64
.
참고 문서