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_valuesDate 上,然后 cumsumSpendCustomer

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'.