python - 是否可以在日期不是数据框索引的 groupby() 之后应用seasonal_decompose()?
问题描述
因此,对于一个预测项目,我有一个非常长的以下类型的多个时间序列的数据框(它有一个数字索引):
日期 | time_series_id | 价值 |
---|---|---|
2015-08-01 | 0 | 0 |
2015-08-02 | 0 | 1 |
2015-08-03 | 0 | 2 |
2015-08-04 | 0 | 3 |
2015-08-01 | 1 | 2 |
2015-08-02 | 1 | 3 |
2015-08-03 | 1 | 4 |
2015-08-04 | 1 | 5 |
我的目标是为这些数据集添加 3 个新列,分别对应于 和 的每个单独的时间序列(每个trend
id seasonal
)resid
。根据数据集的特点,它们往往在日期的开头和结尾都有 Nans。
我试图做的是以下内容:
from statsmodels.tsa.seasonal import seasonal_decompose
df.assign(trend = lambda x: x.groupby("time_series_id")["value"].transform(lambda s: s.mask(~s.isna(), other= seasonal_decompose(s[~s.isna()], model='aditive', extrapolate_trend='freq').trend))
预期输出(趋势值不是实际值)应该是:
日期 | time_series_id | 价值 | 趋势 |
---|---|---|---|
2015-08-01 | 0 | 0 | 1 |
2015-08-02 | 0 | 1 | 1 |
2015-08-03 | 0 | 2 | 1 |
2015-08-04 | 0 | 3 | 1 |
2015-08-01 | 1 | 2 | 1 |
2015-08-02 | 1 | 3 | 1 |
2015-08-03 | 1 | 4 | 1 |
2015-08-04 | 1 | 5 | 1 |
但我收到以下错误消息:
AttributeError: 'Int64Index' object has no attribute 'inferred_freq'
在我的代码的先前迭代中,这适用于我的个人时间序列数据帧,因为我已将该date
列嵌入为数据帧的索引而不是附加列,因此 lambda 函数采用的“x”已经适合该seasonal_decompose
功能的“日期时间”索引。
df.assign(
trend = lambda x: x["value"].mask(~x["value"].isna(), other =
seasonal_decompose(x["value"][~x["value"].isna()], model='aditive', extrapolate_trend='freq').trend))
我的问题是,首先:是否可以使用 groupby 来实现这一点?或者其他方法是可能的:是否可以处理不占用太多内存的问题?我正在处理的原始数据集大约有 1MM ~ 行,因此非常欢迎任何帮助:)。
解决方案
已经提出的解决方案之一是否有效?如果是这样,或者您找到了不同的解决方案,请分享。我尝试了每一个都没有成功,但我是 Python 新手,所以可能遗漏了一些东西。
这是我想出的,使用 for 循环。对于我的数据集,分解包含 6,000 个不同子集的 2000 万行需要 8 分钟。这行得通,但我希望它更快。
约会时间 | 细分 ID | 行程时间(分钟) |
---|---|---|
2021-11-09 07:15:00 | 1 | 30 |
2021-11-09 07:30:00 | 1 | 18 |
2021-11-09 07:15:00 | 2 | 30 |
2021-11-09 07:30:00 | 2 | 17 |
segments = set(frame['Segment ID'])
data = pd.DataFrame([])
for s in segments:
df = frame[frame['Segment ID'] == s].set_index('Date Time').resample('H').mean()
comp = sm.tsa.seasonal_decompose(x=df['Travel Time(Minutes)'], period=24*7, two_sided=False)
df = df.join(comp.trend).join(comp.seasonal).join(comp.resid)
#optional columns with some statistics to find outliers and trend changes
df['resid zscore'] = (df['resid'] - df['resid'].mean()).div(df['resid'].std())
df['trend pct_change'] = df.trend.pct_change()
df['trend pct_change zscore'] = (df['trend pct_change'] - df['trend pct_change'].mean()).div(df['trend pct_change'].std())
data = data.append(df.dropna())
推荐阅读
- c# - 如果在运行任务之前创建新的表单实例,则等待任务挂起
- java - 不显示滚动条
- mysql - 这种关系是 OneToMany 还是 ManyToMany?
- github - 如何在未经管理员许可的情况下访问 Github 和 Bitbucket 上的私有存储库
- r - ggplot R具有相同比例的多个直方图
- r - 编译的 R 代码实际上比启用 JIT 的纯 R 慢
- php - 如何使用来自不和谐 oauth2 登录的访问令牌来获取用户信息
- oracle - Oracle,用户无法访问表空间
- json - 用 JQ 填充 JSON 数组以获得矩形结果
- r - 包含 na.action=na.pass 时 caretEnsemble 失败