python - 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)它自动对结果进行排序并重置索引,就像在“转换”方法中一样。
我想了解为什么会发生这种情况,还有其他方法可以实现上述结果。
解决方案
我采用了你原来的方法并做了一些改变。你能检查这是否是你想要的吗?
重置原始数据框的索引,并为原始索引分配列名。
df = df.reset_index().rename(columns={df.index.name: 'index'})
index
现在,您拥有相同的原始数据框,但它有一个称为原始索引的附加列。
在 2 列和.分组rolling
的数据框上应用和。groupby
group
index
column1
column2
(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
希望这可以帮助!如果我遗漏了什么,请告诉我。
推荐阅读
- azure-devops - 无法在 Microsoft Teams 中设置 Devops Pipelines 应用程序。应用程序卡住
- reactjs - React - 当作为道具传递时,父母的状态变化不会导致孩子的重新渲染?
- c# - 计算更多 foreach 循环的百分比
- typescript - 正确获取嵌套条件映射类型的类型
- javascript - 如何在nodejs中将mmddyyyy日期格式转换为mm/dd/yyyy
- json - 以 json 形式获取 firebase 实时数据库并映射
- ruby-on-rails - Rails:查找或初始化然后在参数中合并
- apache-spark - Spark 流式传输:公开 spark_streaming_* 指标
- apache-kafka - 调用 KStream.join() 后,Kafka 密钥附加了奇怪的字符
- dialogflow-es - 是否可以将消息推送到 Dialogflow 对话?