首页 > 解决方案 > Pandas Groupby 在日期时间列上滚动多列的总和

问题描述

我正在尝试按组获取多列的滚动总和,在日期时间列上滚动(即在指定的时间间隔内)。滚动一列似乎工作正常,但是当我通过矢量化滚动多列时,我得到了意想不到的结果。

我的第一次尝试:

df = pd.DataFrame({"column1": range(6), 
                   "column2": range(6), 
                   'group': 3*['A','B'], 
                   'date':pd.date_range("20190101", periods=6)})

(df.groupby('group').rolling("1d", on='date')['column1'].sum()).groupby('group').shift(fill_value=0)

# output:
group  date      
A      2019-01-01    0.0
       2019-01-03    0.0
       2019-01-05    2.0
B      2019-01-02    0.0
       2019-01-04    1.0
       2019-01-06    3.0
Name: column1, dtype: float64

以上产生了预期的结果,但是我在此过程中丢失了原始索引。由于在我的数据中某些日期是相同的,因此我必须在 group+date 上重新加入原始数据框,这是低效的。因此,我应用了以下方法来避免这种情况并保留原始索引:

df.groupby('group').apply(lambda x: x.rolling("1d", on='date')['column1'].sum().shift(fill_value=0))

# output:
group   
A      0    0.0
       2    0.0
       4    2.0
B      1    0.0
       3    1.0
       5    3.0
Name: column1, dtype: float64

有了这个,我可以通过对索引进行排序轻松地将它分配给原始 df 的新列。现在我想对“column2”重复相同的操作,并通过矢量化来做到这一点。但是,我得到的结果是出乎意料的:

df.groupby('group').apply(lambda x: x.rolling("1d", on='date')[['column1','column2']].sum().shift(fill_value=0))

# output:

   column1  column2       date
0      0.0      0.0 1970-01-01
1      0.0      0.0 1970-01-01
2      0.0      0.0 2019-01-01
3      1.0      1.0 2019-01-02
4      2.0      2.0 2019-01-03
5      3.0      3.0 2019-01-04

结果是正确的,但出于以下原因出乎意料:(1)groupby 中的 group_keys 被忽略(2)它自动对结果进行排序并重置索引,就像在“转换”方法中一样。

我想了解为什么会发生这种情况,还有其他方法可以实现上述结果。

标签: pythonpandas

解决方案


我采用了你原来的方法并做了一些改变。你能检查这是否是你想要的吗?

重置原始数据框的索引,并为原始索引分配列名。

df = df.reset_index().rename(columns={df.index.name: 'index'})

index现在,您拥有相同的原始数据框,但它有一个称为原始索引的附加列。

在 2 列和.分组rolling的数据框上应用和。groupbygroupindexcolumn1column2

(df.groupby(['group', 'index']).rolling("1d", on='date')[['column1', 'column2']].sum()).groupby('group').shift(fill_value=0)

结果:

                        column1  column2
group index date                        
A     0     2019-01-01      0.0      0.0
      2     2019-01-03      0.0      0.0
      4     2019-01-05      2.0      2.0
B     1     2019-01-02      0.0      0.0
      3     2019-01-04      1.0      1.0
      5     2019-01-06      3.0      3.0

如果您想要原始索引,请重置多索引并将“索引”设置为索引

(df.groupby(['group', 'index']).rolling("1d", on='date')[['column1', 'column2']].sum()).groupby('group').shift(fill_value=0).reset_index().set_index('index')

结果:

      group       date  column1  column2
index                                   
0         A 2019-01-01      0.0      0.0
2         A 2019-01-03      0.0      0.0
4         A 2019-01-05      2.0      2.0
1         B 2019-01-02      0.0      0.0
3         B 2019-01-04      1.0      1.0
5         B 2019-01-06      3.0      3.0

.sort_index()如果要排序,请添加

      group       date  column1  column2
index                                   
0         A 2019-01-01      0.0      0.0
1         B 2019-01-02      0.0      0.0
2         A 2019-01-03      0.0      0.0
3         B 2019-01-04      1.0      1.0
4         A 2019-01-05      2.0      2.0
5         B 2019-01-06      3.0      3.0

希望这可以帮助!如果我遗漏了什么,请告诉我。


推荐阅读