Skip to main content
 首页 » 编程设计

python之移位组的滚动总和不适用于第一组条目的数据框

2025年05月04日15shanyou

我在尝试将字段添加到 DataFrame 时遇到问题,该字段汇总了过去三个月(即不包括本月)。

我有一个 DataFrame,它显示与 channel_id 相关的月费:

+-------+---------+------------+----------+-------------------------+ 
| index |  date   | channel_id |   fee    |       NEW COLUMN        | 
+-------+---------+------------+----------+-------------------------+ 
|    10 | 2018-03 |         22 | 24525.88 | (depends on rows above) | 
|    11 | 2018-04 |         22 |    10493 | (depends on rows above) | 
|    12 | 2018-05 |         22 |    12500 | (depends on rows above) | 
|    13 | 2017-10 |         43 |     1000 | 0                       | 
|    14 | 2017-11 |         43 |     1000 | 0                       | 
|    15 | 2017-12 |         43 |     1000 | 0                       | 
|    16 | 2018-01 |         43 |     1000 | 3000                    | 
|    17 | 2018-02 |         43 |     1000 | 3000                    | 
|    18 | 2018-03 |         43 |     1000 | 3000                    | 
|    19 | 2018-04 |         43 |     1000 | 3000                    | 
|    20 | 2018-05 |         43 |     1000 | 3000                    | 
|    21 | 2017-10 |         58 |     1750 | 0                       | 
|    22 | 2017-11 |         58 |     1750 | 0                       | 
|    23 | 2017-12 |         58 |   3302.1 | 0                       | 
|    .. | ..      |         .. |   ..     | ..                      | 
+-------+---------+------------+----------+-------------------------+ 

对于每个 channel_id,我想汇总最近 3 个月的费用。每个 channel_id 的前三个月(例如行索引 4、5、6)应为 0,因为没有前 3 个月的总和。

为了实现这一点,我正在使用:

df.groupby(['channel_id']).rolling(3)[fee].sum().shift(1).sort_index(level=1).fillna(0)

这大部分有效,但对于一些 channel_ids 的第一个实例,它填充了一个我无法绑定(bind)到任何东西的值...:

+---------+------------+----------+----------+----------+ 
|  date   | channel_id |   fee    | NEW_COL  | Correct? | 
+---------+------------+----------+----------+----------+ 
| 2018-03 |         22 | 24525.88 | 52572.85 | YES      | 
| 2018-04 |         22 |    10493 | 60211.76 | YES      | 
| 2018-05 |         22 |    12500 | 53933.88 | YES      | 
| 2017-10 |         43 |     1000 |     2400 | NO!!!    | 
| 2017-11 |         43 |     1000 |        0 | YES      | 
| 2017-12 |         43 |     1000 |        0 | YES      | 
| 2018-01 |         43 |     1000 |     3000 | YES      | 
| 2018-02 |         43 |     1000 |     3000 | YES      | 
| 2018-03 |         43 |     1000 |     3000 | YES      | 
| 2018-04 |         43 |     1000 |     3000 | YES      | 
| 2018-05 |         43 |     1000 |     3000 | YES      | 
| 2017-10 |         58 |     1750 |        0 | YES      | 
| 2017-11 |         58 |     1750 |        0 | YES      | 
| 2017-12 |         58 |   3302.1 |        0 | YES      | 
+---------+------------+----------+----------+----------+ 

我对 df 操作的理解有点粗略,但我对链的理解是:

df.groupby(['channel_id']):按channel_id分组数据

.rolling(3)[fee].sum():将 3 个月的滚动总和应用于 groupby dfs

.shift(1):将值向上移动 1(因为我们不想要当前月份)

.sort_index(level=1):不确定这在上下文中到底做了什么,但它是必需的...

.fillna(0):用 0 填充 NaN,其中前 3 个月不可用。

我尝试过不同的 sort_index 值(和移位),但无法理解这是如何计算出不正确的值的。

请您参考如下方法:

使用应用

df.groupby(['channel_id'])['fee'].apply(lambda x :x.rolling(3).sum().shift(1).fillna(0)) 
Out[319]:  
0        0.0 
1        0.0 
2        0.0 
3        0.0 
4        0.0 
5        0.0 
6     3000.0 
7     3000.0 
8     3000.0 
9     3000.0 
10    3000.0 
11       0.0 
12       0.0 
13       0.0 
Name: fee, dtype: float64