Pandas SUMIFS,行相关过滤器
Pandas SUMIFS, row dependant filters
我正在尝试使用 pandas 进行 SUMIFS 样式计算。 Power Pivots DAX 具有 CALCULATE 功能,可以完美运行,但无法扩展到数百万行。
一个简单的例子是使用 DataFrame 计算累计总计列:
Index Customer Spend Date Cumulative Total
0 A 100 16/08/2017 280
1 A 50 15/08/2017 180
2 B 30 15/08/2017 165
3 A 50 14/08/2017 130
4 B 75 14/08/2017 135
5 C 60 14/08/2017 80
6 A 80 13/08/2017 80
7 B 60 13/08/2017 60
8 C 20 12/08/2017 20
我试过在行上应用一个函数,但速度很慢,df 将是上面的数据框:
def cumulativeSpend(row):
returnvalue = df['Spend'][
(df['Customer']==row['Customer'])
& (df['Date'] <= row['Date'])
].sum()
return returnvalue
行是无序的,可能有一种使用 groupby 的方法,但如果有的话,我还没有想出如何调整它所以日期 <= 每行。
非常感谢
这是一种方法,首先 sort_values
在 Date
上,然后 cumsum
在 Spend
上 Customer
组
In [160]: (df.sort_values('Date')
.groupby('Customer')['Spend']
.transform('cumsum')
.sort_index())
...:
Out[160]:
0 280
1 180
2 165
3 130
4 135
5 80
6 80
7 60
8 20
Name: Spend, dtype: int64
详情
In [161]: df['cumtot'] = (df.sort_values('Date')
.groupby('Customer')['Spend']
.transform('cumsum')
.sort_index())
In [162]: df
Out[162]:
Customer Spend Date Cumulative Total cumtot
0 A 100 2017-08-16 280 280
1 A 50 2017-08-15 180 180
2 B 30 2017-08-15 165 165
3 A 50 2017-08-14 130 130
4 B 75 2017-08-14 135 135
5 C 60 2017-08-14 80 80
6 A 80 2017-08-13 80 80
7 B 60 2017-08-13 60 60
8 C 20 2017-08-12 20 20
注意:如果您的 Date
列是字符串,则
In [158]: df.Date = pd.to_datetime(df.Date, format='%d/%m/%Y')
您可以执行以下操作:
df['Cumulative Spend'] = df.sort_values(by='Date').groupby('Customer')['Spend'].cumsum()
按日期升序排序(注意:如果它们是文本而不是实际的日期时间,这可能会失败)。我们按 'Customer'
分组并将累加和应用于 'Spend'
.
我正在尝试使用 pandas 进行 SUMIFS 样式计算。 Power Pivots DAX 具有 CALCULATE 功能,可以完美运行,但无法扩展到数百万行。
一个简单的例子是使用 DataFrame 计算累计总计列:
Index Customer Spend Date Cumulative Total
0 A 100 16/08/2017 280
1 A 50 15/08/2017 180
2 B 30 15/08/2017 165
3 A 50 14/08/2017 130
4 B 75 14/08/2017 135
5 C 60 14/08/2017 80
6 A 80 13/08/2017 80
7 B 60 13/08/2017 60
8 C 20 12/08/2017 20
我试过在行上应用一个函数,但速度很慢,df 将是上面的数据框:
def cumulativeSpend(row):
returnvalue = df['Spend'][
(df['Customer']==row['Customer'])
& (df['Date'] <= row['Date'])
].sum()
return returnvalue
行是无序的,可能有一种使用 groupby 的方法,但如果有的话,我还没有想出如何调整它所以日期 <= 每行。
非常感谢
这是一种方法,首先 sort_values
在 Date
上,然后 cumsum
在 Spend
上 Customer
组
In [160]: (df.sort_values('Date')
.groupby('Customer')['Spend']
.transform('cumsum')
.sort_index())
...:
Out[160]:
0 280
1 180
2 165
3 130
4 135
5 80
6 80
7 60
8 20
Name: Spend, dtype: int64
详情
In [161]: df['cumtot'] = (df.sort_values('Date')
.groupby('Customer')['Spend']
.transform('cumsum')
.sort_index())
In [162]: df
Out[162]:
Customer Spend Date Cumulative Total cumtot
0 A 100 2017-08-16 280 280
1 A 50 2017-08-15 180 180
2 B 30 2017-08-15 165 165
3 A 50 2017-08-14 130 130
4 B 75 2017-08-14 135 135
5 C 60 2017-08-14 80 80
6 A 80 2017-08-13 80 80
7 B 60 2017-08-13 60 60
8 C 20 2017-08-12 20 20
注意:如果您的 Date
列是字符串,则
In [158]: df.Date = pd.to_datetime(df.Date, format='%d/%m/%Y')
您可以执行以下操作:
df['Cumulative Spend'] = df.sort_values(by='Date').groupby('Customer')['Spend'].cumsum()
按日期升序排序(注意:如果它们是文本而不是实际的日期时间,这可能会失败)。我们按 'Customer'
分组并将累加和应用于 'Spend'
.