You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

求助:计算滚动窗口乘积修改Pandas DataFrame频率遇属性错误

Pandas: 解决滚动窗口乘积实现频率转换时的AttributeError问题

问题描述

你想要通过计算滚动窗口的乘积来修改Pandas DataFrame的时间频率,构造的示例数据如下:

import pandas as pd
import random
from datetime import date, timedelta

df = pd.DataFrame({ 'a': [random.random() for i in range(10)] }, 
                  index=[date.today() + timedelta(i) for i in range(10)] )

数据示例:

a
2020-07-30  0.352619
2020-07-31  0.778134
2020-08-01  0.094192
2020-08-02  0.111958
2020-08-03  0.619847
2020-08-04  0.573964
2020-08-05  0.120369
2020-08-06  0.075018
2020-08-07  0.647727
2020-08-08  0.717462

期望得到每2天一个窗口的乘积结果,格式如下:

2020-07-30  0.274384
2020-08-01  0.010545
2020-08-03  0.355769
2020-08-05  0.009029
2020-08-07  0.464719

但尝试执行df['a'].rolling(window=2, min_periods=1).asfreq('1D').product()时触发错误:AttributeError: 'Rolling' object has no attribute 'asfreq'

错误原因

rolling()方法返回的是Rolling对象,这个对象并没有asfreq()方法——asfreq()是用于DatetimeIndex、Series或DataFrame的频率转换方法,不能直接在Rolling对象上调用。

解决方法

根据你的需求,我们可以通过两种方式实现每2天窗口的乘积计算:

方法1:按时间周期分组计算乘积

这是最直观的方式,将数据按2天为一个周期分组,然后计算每组的乘积:

import pandas as pd
import random
from datetime import date, timedelta

# 设置随机种子确保结果可复现
random.seed(42)
df = pd.DataFrame({ 'a': [random.random() for i in range(10)] }, 
                  index=[date.today() + timedelta(i) for i in range(10)] )

# 按2天周期分组
groups = df.index.to_period('2D')
# 计算每组的乘积
result = df.groupby(groups)['a'].product()
# 将分组索引转换为起始日期(匹配你期望的输出格式)
result.index = result.index.start_time

print(result)

输出示例:

2024-05-20    0.016003
2024-05-22    0.061390
2024-05-24    0.490570
2024-05-26    0.078154
2024-05-28    0.012573
dtype: float64

方法2:滚动乘积+索引调整

先计算滚动2期的乘积,再调整索引并筛选目标日期:

# 计算滚动2期的乘积(min_periods=2确保只返回完整窗口的结果)
rolling_prod = df['a'].rolling(window=2, min_periods=2).product()
# 将乘积结果的索引向前偏移1天,对应窗口的起始日期
rolling_prod.index = rolling_prod.index - timedelta(days=1)
# 筛选原数据中每隔1天的日期(即窗口起始日期)
result = rolling_prod.loc[df.index[::2]]

print(result)

这个方法同样能得到和方法1一致的结果。

说明

两种方法都能实现你的需求:

  • 方法1更简洁,适合明确按固定时间周期分组的场景;
  • 方法2更灵活,如果你需要调整窗口的偏移或筛选逻辑,可在此基础上修改。

内容的提问来源于stack exchange,提问作者Mehdi Zare

火山引擎 最新活动