其余月份的熊猫总和

时间:2020-01-31 12:32:50

标签: python pandas time-series

我有一个看起来像这样的数据框:

import pandas as pd

date = ['28-01-2017','29-01-2017','30-01-2017','31-01-2017','01-02-2017','02-02-2017','...']
sales = [1,2,3,4,1,2,'...']
days_left_in_m = [3,2,1,0,29,28,'...']
df_test = pd.DataFrame({'date': date,'days_left_in_m':days_left_in_m,'sales':sales})

df_test

我正在努力寻找本月剩余时间的销售额。

因此,在2017年1月28日,它将计算接下来3天的总和, 1月29日-接下来2天的总和,依此类推...

结果应类似于下面的“必填”列。

       date    days_left_in_m   sales   required
0   28-01-2017     3              1        10
1   29-01-2017     2              2        9
2   30-01-2017     1              3        7
3   31-01-2017     0              4        4
4   01-02-2017     29             1        3
5   02-02-2017     28             2        2
6   ...           ...            ...      ...

我当前的解决方案确实很丑-我使用了非Python循环:

for i in range(lenght_of_t_series):

        days_left = data_in.loc[i].days_left_in_m

        if days_left == 0:

            sales_temp_list.append(0)
        else:
            if (i+days_left) <= lenght_of_t_series:

                sales_temp_list.append(sum(data_in.loc[(i+1):(i+days_left)].sales))    
            else:
                sales_temp_list.append(np.nan)

我猜想更好的方法是使用df['sales'].rolling(n).sum() 但是,每一行都有一个不同的窗口。

请告知执行此操作的最佳方法...

1 个答案:

答案 0 :(得分:1)

我认为您需要DataFrame.sort_valuesGroupBy.cumsum。 如果您不想考虑当天的情况,可以 使用groupby.shift(请参阅注释代码)。

首先,您可以将日期列转换为datetime以便使用Series.dt.month

df_test['date'] = pd.to_datetime(df_test['date'],format = '%d-%m-%Y')

然后我们可以使用:

months = df_test['date'].dt.month
df_test['required'] = (df_test.sort_values('date',ascending = False)
                              .groupby(months)['sales'].cumsum()
                             #.groupby(months).shift(fill_value = 0)
                        )
print(df_test)

输出

        date  days_left_in_m  sales  required
0 2017-01-28               3      1        10
1 2017-01-29               2      2         9
2 2017-01-30               1      3         7
3 2017-01-31               0      4         4
4 2017-02-01              29      1         3
5 2017-02-02              28      2         2

如果您不想将date列转换为datetime,请使用:

months = pd.to_datetime(df_test['date'],format = '%d-%m-%Y').dt.month
df_test['required'] = (df_test.sort_values('date',ascending = False)
                              .groupby(months)['sales'].cumsum()
                             #.groupby(months).shift(fill_value = 0)
                        )