我在正确执行 additive
模型时遇到一些问题。我有以下数据框:
当我运行这段代码时:
import statsmodels as sm
import statsmodels.api as sm
decomposition = sm.tsa.seasonal_decompose(df, model = 'additive')
fig = decomposition.plot()
matplotlib.rcParams['figure.figsize'] = [9.0,5.0]
我收到了这条信息:
ValueError:您必须指定句点,或者 x 必须是具有 >DatetimeIndex 且 freq 未设置为 None 的 pandas 对象
我应该怎么做才能得到这个例子:
上面的屏幕是我从这个 地方 拿的
原文由 and_and 发布,翻译遵循 CC BY-SA 4.0 许可协议
具有相同的 ValueError,这只是我自己进行的一些测试和少量研究的结果,并没有声称它是完整的或专业的。请评论或回答任何发现错误的人。
当然,您的数据应该按照索引值的正确顺序排列,正如您在回答中所述,您可以使用
df.sort_index(inplace=True)
来保证这一点。这本身并没有错,尽管错误消息与排序顺序无关,而且我已经检查过:当我对手头的一个巨大数据集的索引进行排序时,错误并没有消失。的确,我还必须对 df.index 进行排序,但是 decompose() 也可以处理未排序的数据,其中项目会及时跳到这里和那里:然后你只会得到很多从左到右和向后的蓝线,直到整个图都充满了它。而且,通常情况下,无论如何排序已经是正确的。就我而言,排序无助于修复错误。因此,我也怀疑索引排序是否已修复您的案例中的错误,因为:错误实际上说明了什么?ValueError:您必须指定:
首先,如果您有一个 _列表列_,以便您的时间序列嵌套到现在,请参阅 将带有“列表列”中数据的 pandas df 转换为长格式的时间序列。使用三列:[list of data] + [timestamp] + [duration] 了解如何取消嵌套 列表列 的详细信息。 1.) 和 2.) 都需要这样做。
1. 的详细信息:“您必须指定 [任一] 句点……”
期间的定义
来自 https://www.statsmodels.org/stable/generated/statsmodels.tsa.seasonal.seasonal_decompose.html 的“period, int, optional”:
用整数设置的周期参数表示您希望在数据中出现的周期数。如果您有一个包含 1000 行的 df,其中包含一个 _列表列_(称为 df_nested),并且每个列表包含例如 100 个元素,那么每个循环将有 100 个元素。采取
period = len(df_nested)
(= 周期数)以获得季节性和趋势的最佳分割可能是明智的。如果每个周期的元素随时间变化,其他值可能更好。 _我不确定如何正确设置参数,因此问题 statsmodels seasonal_decompose(): What is the right “period of the series” in the context of a list column (constant vs. varying number of items) on Cross Validated which尚未回答。_选项 1.) 的“period”参数比选项 2.) 有很大的优势。尽管它使用时间索引 (DatetimeIndex) 作为其 x 轴,但与选项 2 相比,它不需要项目准确命中频率。)。相反,它只是将一行中的任何内容连接在一起,优点是您不需要填补任何空白:前一个事件的最后一个值只是与下一个事件的下一个值连接,无论它是否已经在下一秒或第二天。
最大可能的“周期”值是多少?如果你有一个 _列表列_(再次调用 df “ _dfnested “),你应该首先将 列表列 取消嵌套到一个 _普通的列_。最大周期是
len(df_unnested)/2
。示例 1:x 中的 20 个项目(x 是 df_unnested 所有项目的数量)最多可以有一个
period = 10
。示例 2:拥有 20 件物品并采用
period=20
,这会引发以下错误:另一个旁注:为了摆脱有问题的错误,
period = 1
应该已经把它拿走了,但是对于时间序列分析,“=1”并没有揭示任何新的东西,每个周期只是 1 个项目然后,趋势与原始数据相同,季节性为0,残差始终为0。####
示例借自 Convert pandas df with data in a “list column” into a time series in long format。使用三列:[数据列表] + [时间戳] + [持续时间]
结果 df_test[‘listData’] 如下所示:
现在看看不同时期的整数值。
period = 1
:period = 2
:如果您将所有项目的四分之一作为一个周期,则此处为 4(共 16 个项目)。
period = 4
:或者,如果您在此处采用循环的最大可能大小,即 8(共 16 个项目)。
period = 8
:看看 y 轴如何改变它们的比例。
####
您将根据需要增加周期整数。你的问题的最大值:
2. 的详细信息:“…或 x 必须是具有 DatetimeIndex 且频率未设置为 None 的熊猫对象”
要使 x 成为频率未设置为 None 的 DatetimeIndex,您需要使用 .asfreq(‘?’) 和 ?在 https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#offset-aliases 中的各种偏移别名中进行选择。
在您的情况下,此选项 2. 更适合,因为您似乎有一个没有间隙的列表。然后,您的月度数据可能应该作为“月开始频率”引入——>“MS”作为偏移量别名:
请参阅 如何使用 pd.to_datetime() 设置频率? 有关更多详细信息,以及您将如何处理差距。
如果您的数据在时间上高度分散,以至于有太多的间隙需要填补,或者如果时间上的间隙并不重要,那么使用“period”的选项 1 可能是更好的选择。
在我的 df_test 示例中,选项 2 并不好。数据在时间上完全分散,如果我以秒为频率,你会得到:
df_test.asfreq('s')
的输出(=以秒为单位的频率):您在这里看到,虽然我的数据只有 16 行,但引入以秒为单位的频率会强制 df 为 304 行,只能从“08:53:20”延伸到“08:58:23”,这里造成 288 个间隙.更重要的是,在这里你必须准确的时间。如果你有 0.1 甚至 0.12314 秒作为你的实际频率,你将不会用你的索引命中大部分项目。
这是一个以 min 作为偏移量别名的示例,
df_test.asfreq('min')
:我们看到只有第一分钟和最后一分钟被填满,其余的都没有被击中。
以天为偏移别名,
df_test.asfreq('d')
:我们看到您只得到第一行作为结果 df,因为只涵盖了一天。它会给你找到的第一个项目,其余的都被丢弃。
一切的结束
将所有这些放在一起,在您的情况下,选择选项 2,而在我的 df_test 示例中,需要选项 1。