[python] Pandas GroupBy.agg ()를 사용하여 동일한 열의 여러 집계

여러 번 호출하지 않고 f1, f2동일한 열에 두 개의 다른 집계 함수 를 적용하는 pandas 기본 제공 방법이 있습니까?df["returns"]agg()

데이터 프레임의 예 :

import pandas as pd
import datetime as dt

pd.np.random.seed(0)
df = pd.DataFrame({
         "date"    :  [dt.date(2012, x, 1) for x in range(1, 11)],
         "returns" :  0.05 * np.random.randn(10),
         "dummy"   :  np.repeat(1, 10)
}) 

구문 적으로 잘못되었지만 직관적으로 올바른 방법은 다음과 같습니다.

# Assume `f1` and `f2` are defined for aggregating.
df.groupby("dummy").agg({"returns": f1, "returns": f2})

분명히 Python은 중복 키를 허용하지 않습니다. 입력을 표현하는 다른 방법이 agg()있습니까? 아마도 튜플 목록이 [(column, function)]더 잘 작동하여 동일한 열에 여러 함수를 적용 할 수 있습니까? 하지만 agg()사전 만받는 것 같습니다.

내부의 두 기능을 모두 적용하는 보조 기능을 정의하는 것 외에 이에 대한 해결 방법이 있습니까? (어쨌든 집계와 어떻게 작동합니까?)



답변

함수를 목록으로 간단히 전달할 수 있습니다.

In [20]: df.groupby("dummy").agg({"returns": [np.mean, np.sum]})
Out[20]:
           mean       sum
dummy
1      0.036901  0.369012

또는 사전으로 :

In [21]: df.groupby('dummy').agg({'returns':
                                  {'Mean': np.mean, 'Sum': np.sum}})
Out[21]:
        returns
           Mean       Sum
dummy
1      0.036901  0.369012


답변

TLDR; Pandas groupby.agg에는 (1) 여러 열에 대한 집계 및 (2) 열에 대한 여러 집계를 지정하기위한 새롭고 더 쉬운 구문이 있습니다. 따라서 pandas> = 0.25 에 대해 이렇게하려면

df.groupby('dummy').agg(Mean=('returns', 'mean'), Sum=('returns', 'sum'))

           Mean       Sum
dummy
1      0.036901  0.369012

또는

df.groupby('dummy')['returns'].agg(Mean='mean', Sum='sum')

           Mean       Sum
dummy
1      0.036901  0.369012

Pandas> = 0.25 : 명명 된 집계

Pandas는 GroupBy.agg명명 된 집계를 지정하기위한보다 직관적 인 구문을 위해 의 동작을 변경했습니다 . 개선 사항 및 관련 GitHub 문제 GH18366GH26512 대한 0.25 문서 섹션을 참조하십시오 .

문서에서

출력 열 이름을 제어하여 열별 집계를 지원하기 위해 pandas는에서 GroupBy.agg()“명명 된 집계”라는 특수 구문을 허용합니다 . 여기서

  • 키워드는 출력 열 이름입니다.
  • 값은 첫 번째 요소가 선택할 열이고 두 번째 요소가 해당 열에 적용 할 집계 인 튜플입니다. Pandas는 pandas.NamedAgg namedtuple에 [ ‘column’, ‘aggfunc’] 필드를 제공하여 인수가 무엇인지 명확하게합니다. 평소와 같이 집계는 호출 가능 또는 문자열 별칭 일 수 있습니다.

이제 키워드 인수를 통해 튜플을 전달할 수 있습니다. 튜플은 (<colName>, <aggFunc>).

import pandas as pd

pd.__version__
# '0.25.0.dev0+840.g989f912ee'

# Setup
df = pd.DataFrame({'kind': ['cat', 'dog', 'cat', 'dog'],
                   'height': [9.1, 6.0, 9.5, 34.0],
                   'weight': [7.9, 7.5, 9.9, 198.0]
})

df.groupby('kind').agg(
    max_height=('height', 'max'), min_weight=('weight', 'min'),)

      max_height  min_weight
kind
cat          9.5         7.9
dog         34.0         7.5

또는 pd.NamedAgg더 명시 적으로 만드는 (본질적으로 명명 된 튜플)을 사용할 수 있습니다 .

df.groupby('kind').agg(
    max_height=pd.NamedAgg(column='height', aggfunc='max'),
    min_weight=pd.NamedAgg(column='weight', aggfunc='min')
)

      max_height  min_weight
kind
cat          9.5         7.9
dog         34.0         7.5

Series의 경우 더 간단합니다. aggfunc를 키워드 인수에 전달하면됩니다.

df.groupby('kind')['height'].agg(max_height='max', min_height='min')

      max_height  min_height
kind
cat          9.5         9.1
dog         34.0         6.0       

마지막으로 열 이름이 유효한 파이썬 식별자가 아닌 경우 압축을 푼 사전을 사용하십시오.

df.groupby('kind')['height'].agg(**{'max height': 'max', ...})

판다 <0.25

0.24까지의 최신 버전의 Pandas에서는 집계 출력에 대한 열 이름을 지정하기 위해 사전을 사용하는 경우 다음이 표시됩니다 FutureWarning.

df.groupby('dummy').agg({'returns': {'Mean': 'mean', 'Sum': 'sum'}})
# FutureWarning: using a dict with renaming is deprecated and will be removed 
# in a future version

열 이름을 바꾸는 데 사전을 사용하는 것은 v0.20에서 더 이상 사용되지 않습니다. 최신 버전의 pandas에서는 튜플 목록을 전달하여 더 간단하게 지정할 수 있습니다. 이 방법으로 함수를 지정하면 모든 해당 열의 함수는 (이름, 함수) 쌍의 튜플로 지정되어야합니다.

df.groupby("dummy").agg({'returns': [('op1', 'sum'), ('op2', 'mean')]})

        returns
            op1       op2
dummy
1      0.328953  0.032895

또는,

df.groupby("dummy")['returns'].agg([('op1', 'sum'), ('op2', 'mean')])

            op1       op2
dummy
1      0.328953  0.032895


답변

이 작업을 원하십니까 :

In [7]: df.groupby('dummy').returns.agg({'func1' : lambda x: x.sum(), 'func2' : lambda x: x.prod()})
Out[7]:
              func2     func1
dummy
1     -4.263768e-16 -0.188565


답변