【问题标题】:Differencing Time Series & Create Stationary Time Series - Pandas差分时间序列和创建固定时间序列 - Pandas
【发布时间】:2021-06-08 02:14:20
【问题描述】:

我想区分时间序列以使其静止。但是,不能保证通过第一个滞后会使时间序列静止。生成如下示例 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 无关,并且被错误地标记为重复。明确提到了预期的输出,问题的范围与提到的here完全不同。

编辑 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,我们如何从中检索原始系列?

【问题讨论】:

  • 所以你需要test_df['lag2'] = test_df['A'].diff().diff() ?
  • @jezrael 是的,但是如果我必须执行 365 天而不是 2 天,此解决方案将无济于事。此外,如果原始系列的值已知,我还询问了如何将滞后 2 天的系列恢复为原始系列。
  • 好的,可以在示例中添加一些time series 吗?
  • @jezrael 我问的问题完全不同,不是重复的。在我的问题中,我从未问过任何数据转换问题或 NaN。您介意解释一下这个问题是如何得到解答的吗?
  • 重新打开,抱歉。

标签: python pandas time-series


【解决方案1】:

diff(2) 将告诉您 an 和 an-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

上面的小数学表明,Lag 365 将使用具有二项式系数 C365i 的 365 个先前值。所以恕我直言,这样做更简单:

s = df['A']
for i in range(365): s = s.diff()
df['Lag 365'] = s

如果您不想保留中间 Lag i 列。


您可以从 diff-ed 列中检索初始值,前提是您还具有 cumsum 的第一个值:df['Lag 1'].fillna(df.iloc[0,0]).cumsum() 回馈df['A']。因此,为了能够从 n-diff-ed 列恢复初始值,我将使用 diff 的细微变化来保留初始值而不是初始 NaN:

def difx(s):
    return s.diff().combine_first(s)

然后要处理第 4 个差异,我会使用

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...

【讨论】:

  • 你是否建议我是否需要服用Lag 365 我需要重复.diff() 365 次?
  • 我知道Lag 365 将需要 365 个以前的值。我的问题是如何编写代码,这样我就不必写diff() 365 次,这是不可能的。
猜你喜欢
  • 2017-09-28
  • 1970-01-01
  • 2019-01-23
  • 1970-01-01
  • 2014-07-10
  • 2012-03-11
  • 2021-09-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多