我想对时间序列进行差分,使其平稳。然而,不能保证采用第一滞后就能使时间序列平稳。生成一个示例Pandas数据框,如下所示
test = {'A':[10,15,19,24,23]}
test_df = pd.DataFrame(test)
通过使用diff()
方法,我们可以按预期采取第一滞后,但如果我尝试diff(2)
,即如果我想使用2的滞后期,我不会得到预期的结果。
预期输出
+----+-------+-------+
| A | Lag 1 | Lag 2 |
+----+-------+-------+
| 10 | NA | NA |
| 15 | 5 | NA |
| 19 | 4 |-1 |
| 24 | 5 | 1 |
| 23 |-1 |-6 |
+----+-------+-------+
输出结果
+----------------+
| A lag1 lag2 |
+----------------+
| 10 NaN NaN |
| 15 5.0 NaN |
| 19 4.0 9.0 |
| 24 5.0 9.0 |
| 23 -1.0 4.0 |
+----------------+
以上输出是使用test_df['lag2'] = test_df['A'].diff(2)
生成的。如何仅使用Lag 2
时间序列获得预期输出并重新生成实际时间序列?
编辑1此问题与任何数据类型转换或nan无关,并且被错误地标记为重复。期望的输出被清楚地提到,问题的范围与这里提到的完全不同。
编辑2可以使用虚拟数据帧来处理更多的样本。
test = np.random.randint(100, size=500)
test_df = pd.DataFrame(test, columns = ['A'])
编辑3为了更好地解释预期产出,请考虑下面的预期产出。
+----+-------+-------+
| A | Lag 1 | Lag 2 |
+----+-------+-------+
| 10 | NA | NA |
| 15 | 5 | NA |
| 19 | 4 | -1 |
| 24 | 5 | 1 |
| 23 | -1 | -6 |
| 50 | 27 | 28 |
| 34 | -16 | -43 |
| 56 | 22 | 38 |
| 33 | -23 | -45 |
| 26 | -7 | 16 |
| 45 | 19 | 26 |
+----+-------+-------+
test = {'A': [10,15,19,24,23,50,34,56,33,26,45]}
test_df = pd.DataFrame(test)
Lag 1
可以使用test_df['lag1'] = test_df['A'].diff()
。但是要创建lag 2
,我需要创建test_df['lag2'] = test_df['A'].diff().diff()
。这个解决方案在我需要花费365个延迟的情况下不起作用。因此,我需要一个解决方案,取原始系列A
的滞后,然后递归地取lag1
的滞后来生成lag2
,等等。
一旦我们创建了滞后项lag2
,我们如何从它中检索原始序列?
diff(2)
将给出n和n-2之间的差异。您需要的是差分列的项之间的差值。. 简单的数学表明它将是an+ an-2-2 * an-1。这足以解释为什么你没有得到预期的结果。
你想要的是迭代diff()
:
df['Lag 1'] = df['A'].diff()
df['Lag 2'] = df['A'].diff().diff()
对于df = pd.DataFrame({'A': [10,15,19,24,23,50,34,56,33,26,45]}
,它给出了预期的:
A Lag 1 Lag 2
0 10 NaN NaN
1 15 5.0 NaN
2 19 4.0 -1.0
3 24 5.0 1.0
4 23 -1.0 -6.0
5 50 27.0 28.0
6 34 -16.0 -43.0
7 56 22.0 38.0
8 33 -23.0 -45.0
9 26 -7.0 16.0
10 45 19.0 26.0
上面的小数学表明,拉格365将使用二项式系数C365i之前的365个值。所以我认为这样做更简单:
s = df['A']
for i in range(365): s = s.diff()
df['Lag 365'] = s
如果您不想保留中间的Lag i列。
您可以从diffed列检索初始值,前提是您还具有cumsum的第一个值:df['Lag 1'].fillna(df.iloc[0,0]).cumsum()
返回df['A']
。因此,为了能够从n差分列恢复初始值,我将使用diff
的稍微变化来保留初始值,而不是初始NaN:
def difx(s):
return s.diff().combine_first(s)
然后处理第四个差异,我将使用
s = df['A']
for i in range(4): s = difx(s)
s['Lag 4'] = s
它给:
0 10.0
1 -25.0
2 19.0
3 -2.0
4 -9.0
5 41.0
6 -105.0
7 152.0
8 -164.0
9 144.0
10 -51.0
现在可以用
检索初始值s = df['Lag 4']
for i in range(4): s = s.cumsum()
我们得到了预期的初始值:
0 10.0
1 15.0
2 19.0
3 24.0
4 23.0
5 50.0
6 34.0
7 56.0
8 33.0
9 26.0
10 45.0
如果您的系列足够长,您可以为Lag 365做同样的事情,只需将我的示例中的4
替换为365…