尝试使用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
答案 0 :(得分:141)
您想使用transform
这将返回一个索引与df对齐的系列,以便您可以将其添加为新列:
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
答案 1 :(得分:8)
如何使用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
等)。在大多数情况下,大约快至20万条记录时,它或多或少地更快。在那之后,性能实际上取决于数据。
(左:v0.23,右:v0.24)
要知道的另类更好,如果您的框架较小且组数较少,则更好。 。 。但我建议将first
作为首选。认为这还是值得分享的。
基准代码,供参考:
transform
答案 2 :(得分:0)
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]
})
print(pd.pivot_table(data=df,index='Date',columns='Sym', aggfunc={'Data2':'sum','Data3':'sum'}))
输出
Data2 Data3
Sym aapl aaww aapl aaww
Date
2015-05-05 15 40 1 120
2015-05-06 10 100 6 60
2015-05-07 8 60 8 100
2015-05-08 11 110 5 50