Pandas groupby (). sum ()의 출력에서 ​​새 열을 어떻게 생성합니까?


82

groupby계산 에서 새 열을 만들려고합니다 . 아래 코드에서 각 날짜 (아래 그룹 참조)에 대해 올바른 계산 된 값을 얻지 만 새 열 ( df['Data4']) 을 만들려고 하면 NaN이 표시됩니다. 따라서 Data3모든 날짜 의 합계를 사용하여 데이터 프레임에 새 열을 만들고 각 날짜 행에 적용하려고합니다. 예를 들어 2015-05-08은 2 개 행 (총계는 50 + 5 = 55)이고이 새 열에는 두 행 모두에 55 개가 있습니다.

import pandas as pd
import numpy as np
from pandas import DataFrame

df = pd.DataFrame({
    'Date' : ['2015-05-08', '2015-05-07', '2015-05-06', '2015-05-05', '2015-05-08', '2015-05-07', '2015-05-06', '2015-05-05'], 
    'Sym'  : ['aapl', 'aapl', 'aapl', 'aapl', 'aaww', 'aaww', 'aaww', 'aaww'], 
    'Data2': [11, 8, 10, 15, 110, 60, 100, 40],
    'Data3': [5, 8, 6, 1, 50, 100, 60, 120]
})

group = df['Data3'].groupby(df['Date']).sum()

df['Data4'] = group

답변:


189

transform이것을 사용 하면 인덱스가 df에 정렬 된 Series가 반환되므로 새 열로 추가 할 수 있습니다.

In [74]:

df = pd.DataFrame({'Date': ['2015-05-08', '2015-05-07', '2015-05-06', '2015-05-05', '2015-05-08', '2015-05-07', '2015-05-06', '2015-05-05'], 'Sym': ['aapl', 'aapl', 'aapl', 'aapl', 'aaww', 'aaww', 'aaww', 'aaww'], 'Data2': [11, 8, 10, 15, 110, 60, 100, 40],'Data3': [5, 8, 6, 1, 50, 100, 60, 120]})
​
df['Data4'] = df['Data3'].groupby(df['Date']).transform('sum')
df
Out[74]:
   Data2  Data3        Date   Sym  Data4
0     11      5  2015-05-08  aapl     55
1      8      8  2015-05-07  aapl    108
2     10      6  2015-05-06  aapl     66
3     15      1  2015-05-05  aapl    121
4    110     50  2015-05-08  aaww     55
5     60    100  2015-05-07  aaww    108
6    100     60  2015-05-06  aaww     66
7     40    120  2015-05-05  aaww    121

다음과 같이 두 번째 groupby가 있으면 어떻게
되나요?

@Mr_and_Mrs_D 당신은 인덱스를 재설정하고이 경우 열을 다시 추가하려면 공통 열에 대해 왼쪽 병합을 수행해야합니다
EdChum

10
또는 사용할 수 있습니다 df.groupby('Date')['Data3'].transform('sum')(기억하기가 약간 더 쉽습니다).
Cleb

39

Groupby (). Sum ()으로 새 열을 어떻게 생성합니까?

두 가지 방법이 있습니다. 하나는 간단하고 다른 하나는 약간 더 흥미 롭습니다.


모두가 좋아하는 항목 : GroupBy.transform() 함께'sum'

@Ed Chum의 대답은 약간 단순화 될 수 있습니다. DataFrame.groupby대신 전화하십시오 Series.groupby. 그 결과 구문이 더 간단 해집니다.

# The setup.
df[['Date', 'Data3']]

         Date  Data3
0  2015-05-08      5
1  2015-05-07      8
2  2015-05-06      6
3  2015-05-05      1
4  2015-05-08     50
5  2015-05-07    100
6  2015-05-06     60
7  2015-05-05    120

df.groupby('Date')['Data3'].transform('sum')

0     55
1    108
2     66
3    121
4     55
5    108
6     66
7    121
Name: Data3, dtype: int64 

조금 더 빠릅니다.

df2 = pd.concat([df] * 12345)

%timeit df2['Data3'].groupby(df['Date']).transform('sum')
%timeit df2.groupby('Date')['Data3'].transform('sum')

10.4 ms ± 367 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
8.58 ms ± 559 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

독창적이지만 고려할만한 가치가있는 : GroupBy.sum()+Series.map()

API에서 흥미로운 특이점을 발견했습니다. 내가 말한 바에 따르면 0.20 이상의 모든 주요 버전에서이를 재현 할 수 있습니다 (0.23 및 0.24에서 테스트했습니다). transform대신 직접 기능을 사용하고 다음을 사용하여 GroupBy방송하면 몇 밀리 초의 시간을 일관되게 줄일 수있는 것 같습니다 map.

df.Date.map(df.groupby('Date')['Data3'].sum())

0     55
1    108
2     66
3    121
4     55
5    108
6     66
7    121
Name: Date, dtype: int64

비교

df.groupby('Date')['Data3'].transform('sum')

0     55
1    108
2     66
3    121
4     55
5    108
6     66
7    121
Name: Data3, dtype: int64

내 시험은 보여 map조금 더 빨리 당신이 직접 사용할 줄 수있는 경우에 GroupBy기능 (예 : mean, min, max, first, 등). 대부분의 일반적인 상황에서 약 200,000 개의 레코드까지 다소 빠릅니다. 그 후 성능은 실제로 데이터에 달려 있습니다.

(왼쪽 : v0.23, 오른쪽 : v0.24)

알아두면 좋은 대안이며, 그룹 수가 적은 작은 프레임이있는 경우 더 좋습니다. . . 그러나 나는 추천 할 것이다transform 첫 번째 선택으로 합니다. 어쨌든 공유 할 가치가 있다고 생각했습니다.

참조 용 벤치마킹 코드 :

import perfplot

perfplot.show(
    setup=lambda n: pd.DataFrame({'A': np.random.choice(n//10, n), 'B': np.ones(n)}),
    kernels=[
        lambda df: df.groupby('A')['B'].transform('sum'),
        lambda df:  df.A.map(df.groupby('A')['B'].sum()),
    ],
    labels=['GroupBy.transform', 'GroupBy.sum + map'],
    n_range=[2**k for k in range(5, 20)],
    xlabel='N',
    logy=True,
    logx=True
)

1
알아두면 좋습니다! (최소한 미래의 perfplots) 버전 번호를 포함 해 주시겠습니까? 성능 차이는 흥미롭지 만, 결국 이것들은 미래에 다룰 수있는 구현 세부 사항입니다. 특히 개발자가 게시물을 메모하는 경우.
jpp

@jpp yup 공평합니다! 버전을 추가했습니다. 이것은 0.23에서 테스트되었지만 0.20 이상의 버전을 사용하는 한 차이가 있다고 생각합니다.
cs95
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.