Python/NumPy | Pandas

[Pandas] NamedAgg - 그룹 연산 시 컬럼 이름 지정

비번변경 2024. 2. 27. 02:20

개요

Pandas에서 DataFrame에 대해 groupby로 여러 컬럼에 여러 연산을 적용하면 멀티 인덱스 컬럼 형태의 결과를 반환받을 수 있다.

df.groupby('a', dropna=False).agg([list, 'count', 'size'])

Pandas 공식 문서 https://pandas.pydata.org/docs/user_guide/advanced.html를 보면 멀티 인덱스 컬럼을 사용한 인덱싱 방법을 상세하게 설명하고 있지만, 아무래도 다소 복잡한 것 같아 그룹 연산한 결과를 단일 인덱스 컬럼 형태로 반환받고 싶다.

방법을 적어둔다.

 

 

named aggregation

Pandas에서 agg 함수를 사용할 때 컬럼에 대한 연산 출력 이름을 제어할 수 있도록 named aggregation을 지원하고 있다. agg 함수에 키워드 매개 변수로 결과 컬럼의 이름과 연산 대상이 되는 컬럼, 그리고 연산할 함수를 지정하면 된다.

df.groupby("<그룹화 기준 컬럼>").agg(
    <결과 컬럼 이름>=pd.NamedAgg(column="<연산 대상 컬럼>", aggfunc="<연산 함수>"),
    <결과 컬럼 이름>=pd.NamedAgg(column="<연산 대상 컬럼>", aggfunc="<연산 함수>")
)

NamdeAgg 튜플 대신 일반 튜플로 지정해도 된다.

df.groupby("<그룹화 기준 컬럼>").agg(
    <결과 컬럼 이름>=(column="<연산 대상 컬럼>", aggfunc="<연산 함수>"),
    <결과 컬럼 이름>=(column="<연산 대상 컬럼>", aggfunc="<연산 함수>")
)

 

 

사용 예시

예시 데이터

df = pd.DataFrame({
  'a': ['A', 'A', 'B', 'B', 'B', None],
  'b': [1, 2, 5, None, 4, 6],
  'c': ['x', 'y', 'z', 'x', 'y', 'z']
})

a 컬럼을 기준으로 그룹화하여 다른 컬럼을 리스트로 변환하고, count, size 함수를 적용하면 아래 사진과 같은 결과를 얻을 수 있다.

df.groupby('a', dropna=False).agg([list, 'count', 'size'])

각 멀티 인덱스 컬럼을 다음과 같이 지정해 본다.

df['b']['list'] -> df['list_b']
df['b']['count'] -> df['cnt_b']
df['b']['size'] -> df['size_b']

컬럼 c에 대해서도 동일한 형식으로 지정하려고 한다.

 

NamedAgg 튜플 사용

df.groupby('a', dropna=False).agg(list_b=pd.NamedAgg('b', list), cnt_b=pd.NamedAgg('b', 'count'), size_b=pd.NamedAgg('b', 'size'),
                                  list_c=pd.NamedAgg('c', list), cnt_c=pd.NamedAgg('c', 'count'), size_c=pd.NamedAgg('c', 'size'))

 

일반 튜플 사용

df.groupby('a', dropna=False).agg(list_b=('b', list), cnt_b=('b', 'count'), size_b=('b', 'size'),
                                  list_c=('c', list), cnt_c=('c', 'count'), size_c=('c', 'size'))

보다 간결하게 표현할 때는 일반 튜플을 사용하는 것이 좋을 거 같다.

 

 

참고 문서

https://pandas.pydata.org/docs/reference/api/pandas.core.groupby.DataFrameGroupBy.agg.html

 

 

728x90