라떼군 이야기


Pandas groupby.apply의 DeprecationWarning: grouping columns 경고 해결 방법

Problem

Pandas 라이브러리를 2.2.0 버전 이상으로 업데이트한 후, 기존에 문제없이 작동하던 데이터 처리 스크립트에서 갑자기 DeprecationWarning이 발생하는 경우가 있습니다. 구체적으로 df.groupby(...).apply(...)를 사용할 때 다음과 같은 경고 메시지가 출력됩니다.

DeprecationWarning: DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation.

이는 그룹화의 기준이 된 컬럼(grouping columns)이 apply 함수 내부로 전달되는 방식이 변경될 예정임을 알리는 경고입니다.

Background

Pandas 2.2.0 이전 버전에서는 groupby 연산을 수행할 때, 각 그룹별로 생성된 서브 데이터프레임 안에 ‘그룹화의 기준이 된 컬럼’이 그대로 포함되어 있었습니다. 예를 들어 df.groupby('category').apply(func)를 실행하면 func에 전달되는 데이터프레임에는 category 컬럼이 들어있었습니다.

하지만 이는 sum()이나 mean() 같은 전체 집계 함수를 사용할 때, 의도치 않게 그룹 키(예: 숫자 ID)까지 연산에 포함시켜 결과를 왜곡하는 버그를 유발하곤 했습니다. Pandas 개발팀은 버전 3.0부터는 그룹 키를 연산 대상에서 기본적으로 제외하기로 결정했으며, 현재 버전(2.2.x)에서는 이 변경 사항을 미리 알리기 위해 include_groups=False를 명시하지 않으면 경고를 띄우도록 변경되었습니다.

Solution

이 경고를 해결하고 향후 Pandas 버전과의 호환성을 유지하기 위한 방법은 크게 세 가지가 있습니다.

1. include_groups=False 파라미터 추가 (권장)

가장 간단하고 권장되는 방법은 apply 메서드에 include_groups=False를 명시적으로 전달하는 것입니다. 이는 Pandas 3.0의 기본 동작과 동일하게 그룹화 컬럼을 연산에서 제외합니다.

import pandas as pd

# 예시 데이터 생성
data = {
    'Category': ['A', 'A', 'B', 'B'],
    'Value': [10, 20, 30, 40],
    'ID': [1, 1, 2, 2]
}
df = pd.DataFrame(data)

# 기존 코드 (경고 발생)
# result = df.groupby('Category').apply(lambda x: x.sum())

# 해결 방법: include_groups=False 추가
# 그룹핑 기준인 'Category' 컬럼은 sum() 연산에서 제외됨
result = df.groupby('Category').apply(lambda x: x.sum(), include_groups=False)

print(result)
# 출력 결과:
#           Value  ID
# Category           
# A            30   2
# B            70   4

2. 연산에 필요한 컬럼 명시적 선택

groupby 객체에서 연산에 필요한 컬럼만 미리 선택한 후 apply를 호출하면, 그룹핑 컬럼이 포함될 여지가 없으므로 경고가 사라집니다.

# 'Category'로 그룹화하되, 'Value'와 'ID' 컬럼만 선택하여 연산 수행
result = df.groupby('Category')[['Value', 'ID']].apply(lambda x: x.sum())

print(result)

3. 그룹핑 컬럼을 인덱스로 설정

데이터프레임의 인덱스를 미리 설정하여 그룹화하는 방법도 있습니다. 이 경우 그룹핑 컬럼이 데이터 영역(columns)이 아닌 인덱스(index)에 위치하므로 연산 대상에서 자연스럽게 제외됩니다.

# 'Category'를 인덱스로 설정 후 그룹화
result = df.set_index('Category').groupby(level='Category').apply(lambda x: x.sum())

print(result)

Deep Dive

include_groups=True(기존 동작)와 include_groups=False(새로운 동작)의 차이는 단순한 경고 제거 이상의 의미가 있습니다. 특히 그룹핑 컬럼이 수치형 데이터일 때 결과값 자체가 달라질 수 있습니다.

예를 들어, 숫자 ID 컬럼으로 그룹화하여 평균(mean)을 구한다고 가정해 봅시다.

  • 기존 동작 (True): ID 컬럼도 데이터에 포함되므로, ID의 평균값(자기 자신)이 결과에 포함됩니다.
  • 새로운 동작 (False): ID 컬럼은 그룹 식별자로만 사용되고 연산에서 제외되므로, 실제 분석 대상인 다른 수치 컬럼들의 평균만 계산됩니다.

따라서 include_groups=False를 사용하는 것은 단순히 경고를 끄는 것이 아니라, 데이터 분석의 논리적 오류를 방지하고 더 명확한 코드를 작성하는 방향입니다.

Conclusion

Pandas의 DeprecationWarning은 버전 3.0에서의 변화를 예고하는 중요한 신호입니다. groupby().apply() 사용 시 include_groups=False를 추가함으로써 경고를 해결할 뿐만 아니라, 그룹핑 컬럼이 연산에 불필요하게 포함되는 부작용을 막을 수 있습니다. 코드를 최신 상태로 유지하고 잠재적인 버그를 예방하기 위해 이 옵션을 적극적으로 사용하는 것을 권장합니다.

References

협업 및 후원 연락하기 →