목차
파이썬의 라이브러리인 pandas에는 데이터를 그룹화하고 그룹별 연산을 수행하기 위해 groupby()라는 함수를 제공합니다. groupby()를 왜 사용하는지, 기본 형태는 어떠한지를 알아보고 기본형태 내 인자들에 대한 설명을 하려고 합니다. 또한, 각 인자들이 어떠한 역할을 하는지 예제 코드를 통해 알아보도록 하겠습니다.
1. Groupby() 함수는 언제 사용하는가?
groupby() 함수는 기본적으로 데이터 프레임 내 특정값을 기준으로 그룹화를 하고 그룹별로 연산을 할 수 있도록 합니다. 또한, 분리된 그룹에 독립적으로 함수를 적용하거나 조건을 기반으로 그룹을 필터링할 때 사용할 수 있습니다. 다음과 같이 목적별로 구분한 내용을 참고하시기 바랍니다.
집계(Aggregation):
데이터를 그룹화하고 그룹별로 집계 연산을 수행할 때 사용됩니다. 예를 들어, 그룹별 평균, 합계, 최댓값, 최솟값 등을 계산할 수 있습니다.
분할-적용(Split-Apply):
데이터를 여러 그룹으로 분할한 후, 각 그룹에 대해 독립적으로 함수를 적용할 때 사용됩니다. 그룹별로 특정 작업을 수행하고 결과를 반환할 수 있습니다.
필터링(Filtering):
그룹화된 데이터에서 조건을 기반으로 그룹을 필터링할 때 사용됩니다. 조건에 맞는 그룹만 선택하여 작업을 수행할 수 있습니다.
변환(Transforming):
그룹 내에서 데이터를 변환하거나 정규화하는 작업을 수행할 때 사용됩니다. 각 그룹 내에서 데이터를 조작하고 변환할 수 있습니다.
아래와 같이 위의 목적에 맞는 예제코드를 확인하면 목적의 의미를 확인하는데 도움이 될 겁니다.
import pandas as pd
# 예제 데이터프레임 생성
data = {
'Country': ['USA', 'USA', 'USA', 'China', 'China', 'China'],
'Year': [2010, 2010, 2015, 2010, 2015, 2015],
'Population': [309, 318, 324, 1340, 1404, 1416]
}
df = pd.DataFrame(data)
# 1. 집계 (Aggregation)
# 국가별로 평균 인구 계산
avg_population_by_country = df.groupby('Country')['Population'].mean()
print(avg_population_by_country)
# 출력:
# Country
# China 1386.666667
# USA 317.000000
# Name: Population, dtype: float64
# 2. 분할-적용 (Split-Apply)
# 각 연도마다 가장 인구가 많은 국가 선택
max_population_country_by_year = df.groupby('Year').apply(lambda x: x.loc[x['Population'].idxmax()])
print(max_population_country_by_year)
# 출력:
# Country Year Population
# Year
# 2010 USA 2010 318
# 2015 China 2015 1416
# 3. 필터링 (Filtering)
# 2010년에 인구가 300 이상인 국가 그룹 선택
filtered_group = df.groupby('Year').filter(lambda x: x['Population'].sum() >= 300)
print(filtered_group)
# 출력:
# Country Year Population
# 0 USA 2010 309
# 1 USA 2010 318
# 3 China 2010 1340
# 4. 변환 (Transforming)
# 각 국가의 인구를 전체 인구 대비 비율로 변환
normalized_population = df.groupby('Country')['Population'].transform(lambda x: x / x.sum())
df['Normalized Population'] = normalized_population
print(df)
# 출력:
# Country Year Population Normalized Population
# 0 USA 2010 309 0.971698
# 1 USA 2010 318 1.000000
# 2 USA 2015 324 1.000000
# 3 China 2010 1340 0.956204
# 4 China 2015 1404 0.993197
# 5 China 2015 1416 1.000000
2. Groupby() 함수의 기본 형태와 인자들
판다스의 데이터프레임 내 함수인 groupby() 함수의 기본형태는 아래와 같습니다.
DataFrame.groupby(
by=None,
axis=0,
level=None,
as_index=True,
sort=True,
group_keys=True,
squeeze=False,
observed=False,
dropna=True,
)
각 인자들의 설명입니다.
by: 그룹화할 기준이 되는 열 또는 열의 리스트입니다. 그룹화할 기준을 지정합니다.
axis: 그룹화할 축을 지정합니다. 기본값은 0으로, 행 기준으로 그룹화를 수행합니다. 1로 설정하면 열 기준으로 그룹화를 수행합니다.
level: 계층적 인덱스가 있는 경우 그룹화할 레벨을 지정합니다.
as_index: 그룹화한 열을 인덱스로 사용할지 여부를 지정합니다. 기본값은 True로, 그룹화한 열을 인덱스로 사용합니다.
sort: 그룹화한 결과를 정렬할지 여부를 지정합니다. 기본값은 True로, 그룹화한 결과를 정렬합니다.
group_keys: 그룹화한 결과의 인덱스 계층에 그룹 키를 추가할지 여부를 지정합니다. 기본값은 True로, 그룹 키를 인덱스 계층에 추가합니다.
squeeze: 그룹화 결과가 단일 그룹인 경우에는 Series로 반환할지 여부를 지정합니다. 기본값은 False로, 그룹화 결과가 DataFrame으로 반환됩니다.
observed: Categorical 데이터의 경우, 관측되지 않은 카테고리를 포함할지 여부를 지정합니다. 기본값은 False로, 관측되지 않은 카테고리를 포함하지 않습니다.
dropna: 그룹화할 때 결측치를 제외할지 여부를 지정합니다. 기본값은 True로, 결측치가 있는 행은 그룹화에서 제외됩니다.
3. 각 인자들의 이해를 돕기 위한 예제 코드
다음은 각 인자들을 활용하여 어떠한 결과가 나오는지 알아보기 위한 예제 코드입니다.
import pandas as pd
# 예제 데이터프레임 생성
data = {
'Category': ['A', 'A', 'B', 'B', 'A', 'B'],
'Subcategory': ['X', 'Y', 'X', 'Y', 'X', 'Y'],
'Value': [10, 20, 30, 40, 50, 60]
}
df = pd.DataFrame(data)
# by 인자: Category로 그룹화
grouped_by_category = df.groupby(by='Category')
print(grouped_by_category.sum())
# 출력:
# Value
# Category
# A 80
# B 130
# axis 인자: 열 기준으로 그룹화
grouped_by_column = df.groupby(axis=1)
print(grouped_by_column.sum())
# 출력:
# Value
# 0 10
# 1 20
# 2 30
# 3 40
# 4 50
# 5 60
# level 인자: MultiIndex를 가진 데이터프레임의 레벨 기준으로 그룹화
df.set_index(['Category', 'Subcategory'], inplace=True)
grouped_by_level = df.groupby(level='Category')
print(grouped_by_level.sum())
# 출력:
# Value
# Category
# A 80
# B 130
# as_index 인자: 그룹화한 열을 인덱스로 사용하지 않음
grouped_without_index = df.groupby('Category', as_index=False).sum()
print(grouped_without_index)
# 출력:
# Category Value
# 0 A 80
# 1 B 130
# sort 인자: 그룹화 결과를 정렬하지 않음
grouped_unsorted = df.groupby('Category', sort=False).sum()
print(grouped_unsorted)
# 출력:
# Value
# Category
# A 80
# B 130
# group_keys 인자: 그룹 키를 인덱스 계층에 추가하지 않음
grouped_no_keys = df.groupby('Category', group_keys=False).sum()
print(grouped_no_keys)
# 출력:
# Value
# Category
# A 80
# B 130
# squeeze 인자: 단일 그룹인 경우 Series로 반환
grouped_squeezed = df.groupby('Category', squeeze=True).sum()
print(grouped_squeezed)
# 출력:
# Category
# A 80
# B 130
# Name: Value, dtype: int64
# observed 인자: Categorical 데이터의 관측되지 않은 카테고리 포함
df['Category'] = pd.Categorical(df['Category'], categories=['A', 'B', 'C'])
grouped_observed = df.groupby('Category', observed=True).sum()
print(grouped_observed)
# 출력:
# Value
# Category
# A 80
# B 130
# C 0
# dropna 인자: 결측치를 포함하여 그룹화
df.loc[3, 'Value'] = None
grouped_with_na = df.groupby('Category', dropna=False).sum()
print(grouped_with_na)
# 출력:
# Value
# Category
# A 80
# B 130
# C 0
4. 마치며
지금까지 python 라이브러리 중 pandas의 dataframe 내 groupby() 함수의 사용 목적과 기본 형태 그리고 그 안의 인자들에 대해서 정리해 보았습니다. 본 포스팅에서 정리한 내용은 기본적인 내용으로 실제 코드에 적용하기 위해서는 변형과 응용이 필요합니다. 각 예제들을 이해해 보고 활용에 도움이 됐으면 합니다.