Groupby (). Sum ()으로 새 열을 어떻게 생성합니까?
두 가지 방법이 있습니다. 하나는 간단하고 다른 하나는 약간 더 흥미 롭습니다.
모두가 좋아하는 항목 : GroupBy.transform()
함께'sum'
@Ed Chum의 대답은 약간 단순화 될 수 있습니다. DataFrame.groupby
대신 전화하십시오 Series.groupby
. 그 결과 구문이 더 간단 해집니다.
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
)