7.6 时间序列的偏移 (shift) Pandas 时间序列数据处理:7.6 时间序列的偏移 (Shift) 在 Pandas 中,时间序列的偏移 (shift) 是一种强大的工具,用于将数据在时间轴上向前或向后移动。这在许多时间序列分析任务中非常有用,例如计算变化率、创建滞后特征、对齐不同频率的时间序列等。 7.6.1 函数的基本用法 函数是 Pandas 和 对象的方法,用于执行偏移操作。其基本语法如下: 参数解释: : 指定要移动的偏移量。正数表示向下移动(未来的数据移到过去),负数表示向上移动(过去的数据移到未来)。默认为 1。 : 如果时间序列具有时间索引,则可以使用 参数指定时间规则字符串来移动时间索引,而不是移动数据。例如, 表示按天移动, 表示按小时移动。
在 Pandas 中,时间序列的偏移 (shift) 是一种强大的工具,用于将数据在时间轴上向前或向后移动。这在许多时间序列分析任务中非常有用,例如计算变化率、创建滞后特征、对齐不同频率的时间序列等。
shift() 函数的基本用法shift() 函数是 Pandas Series 和 DataFrame 对象的方法,用于执行偏移操作。其基本语法如下:
DataFrame.shift(periods=1, freq=None, axis=0, fill_value=None) Series.shift(periods=1, freq=None, axis=0, fill_value=None)
参数解释:
periods: 指定要移动的偏移量。正数表示向下移动(未来的数据移到过去),负数表示向上移动(过去的数据移到未来)。默认为 1。
freq: 如果时间序列具有时间索引,则可以使用 freq 参数指定时间规则字符串来移动时间索引,而不是移动数据。例如,freq='D' 表示按天移动,freq='H' 表示按小时移动。
axis: 指定移动的轴。默认为 0,表示按行移动(对 Series 来说总是如此)。对于 DataFrame,可以设置为 1 表示按列移动。
fill_value: 指定移动后产生的缺失值的填充值。默认为 NaN。
import pandas as pd # 创建一个示例 Series data = pd.Series([10, 20, 30, 40, 50]) print("原始数据:\n", data) # 向下移动 1 个位置 shifted_down = data.shift(1) print("\n向下移动 1 个位置:\n", shifted_down) # 向上移动 2 个位置 shifted_up = data.shift(-2) print("\n向上移动 2 个位置:\n", shifted_up) # 使用 fill_value 填充缺失值 shifted_down_filled = data.shift(1, fill_value=0) print("\n向下移动 1 个位置,填充 0:\n", shifted_down_filled)
输出:
原始数据: 0 10 1 20 2 30 3 40 4 50 dtype: int64 向下移动 1 个位置: 0 NaN 1 10.0 2 20.0 3 30.0 4 40.0 dtype: float64 向上移动 2 个位置: 0 30.0 1 40.0 2 50.0 3 NaN 4 NaN dtype: float64 向下移动 1 个位置,填充 0: 0 0 1 10 2 20 3 30 4 40 dtype: int64
import pandas as pd import numpy as np # 创建一个时间序列 dates = pd.date_range('2023-01-01', periods=5, freq='D') ts = pd.Series(np.arange(5), index=dates) print("原始时间序列:\n", ts) # 使用 periods 偏移 shifted_ts = ts.shift(2) print("\n使用 periods 偏移:\n", shifted_ts) # 使用 freq 偏移时间索引 shifted_ts_freq = ts.shift(periods=2, freq='D') # shift(freq='2D') 也可以 print("\n使用 freq 偏移时间索引:\n", shifted_ts_freq)
输出:
原始时间序列: 2023-01-01 0 2023-01-02 1 2023-01-03 2 2023-01-04 3 2023-01-05 4 Freq: D, dtype: int64 使用 periods 偏移: 2023-01-01 NaN 2023-01-02 NaN 2023-01-03 0.0 2023-01-04 1.0 2023-01-05 2.0 Freq: D, dtype: float64 使用 freq 偏移时间索引: 2023-01-03 0 2023-01-04 1 2023-01-05 2 2023-01-06 3 2023-01-07 4 Freq: D, dtype: int64
注意 periods 和 freq 的区别:
periods 移动的是数据,索引不变。
freq 移动的是索引,数据和索引的对应关系发生改变。
import pandas as pd import numpy as np # 创建一个示例 DataFrame dates = pd.date_range('2023-01-01', periods=5, freq='D') df = pd.DataFrame({'A': np.arange(5), 'B': np.arange(5, 10)}, index=dates) print("原始 DataFrame:\n", df) # 按行向下移动 shifted_df_row = df.shift(1) print("\n按行向下移动:\n", shifted_df_row) # 按列向右移动 shifted_df_col = df.shift(1, axis=1) print("\n按列向右移动:\n", shifted_df_col)
输出:
原始 DataFrame: A B 2023-01-01 0 5 2023-01-02 1 6 2023-01-03 2 7 2023-01-04 3 8 2023-01-05 4 9 按行向下移动: A B 2023-01-01 NaN NaN 2023-01-02 0.0 5.0 2023-01-03 1.0 6.0 2023-01-04 2.0 7.0 2023-01-05 3.0 8.0 按列向右移动: A B 2023-01-01 NaN 0.0 2023-01-02 NaN 1.0 2023-01-03 NaN 2.0 2023-01-04 NaN 3.0 2023-01-05 NaN 4.0
shift() 的应用场景计算变化率: 可以使用 shift() 函数计算时间序列数据的变化率。
import pandas as pd import numpy as np dates = pd.date_range('2023-01-01', periods=5, freq='D') ts = pd.Series(np.random.randn(5), index=dates) print("原始时间序列:\n", ts) # 计算一阶差分 diff = ts - ts.shift(1) print("\n一阶差分:\n", diff) # 计算变化率 change_rate = ts.pct_change() print("\n变化率:\n", change_rate)
创建滞后特征: 在机器学习中,经常需要将过去的数据作为特征来预测未来的值。shift() 函数可以方便地创建滞后特征。
import pandas as pd import numpy as np dates = pd.date_range('2023-01-01', periods=5, freq='D') df = pd.DataFrame({'value': np.random.randn(5)}, index=dates) # 创建滞后 1 天和 2 天的特征 df['lag_1'] = df['value'].shift(1) df['lag_2'] = df['value'].shift(2) print(df)
对齐不同频率的时间序列: 当需要将不同频率的时间序列进行比较或合并时,可以使用 shift() 函数进行对齐。 这通常需要结合 resample() 函数一起使用。
检测时间序列的模式: 通过将时间序列与其自身的偏移版本进行比较,可以检测时间序列中的周期性模式。
tshift() (已弃用)在较早的 Pandas 版本中,有一个 tshift() 函数用于移动时间索引。 但是,tshift() 已经被 shift(freq=...) 取代,所以不建议使用。
shift() 函数会产生缺失值 (NaN),需要根据实际情况进行处理(例如,填充、删除等)。
理解 periods 和 freq 参数的区别至关重要。 periods 移动的是数据,而 freq 移动的是时间索引。
在处理 DataFrame 时,要明确指定 axis 参数,以确定是按行还是按列移动。
以下是一个简单的 Mermaid 图表,展示了 shift() 函数的工作原理:
代码解释:
A[原始数据]: 代表原始的时间序列数据。
B{shift(periods=1)}: 表示应用 shift(periods=1) 函数,将数据向下移动一个位置。
C[偏移后的数据 (向下移动)]: 表示移动后的数据,其中第一个值为 NaN,其他值向下移动。
D[原始数据]: 代表原始的时间序列数据。
E{shift(periods=-1)}: 表示应用 shift(periods=-1) 函数,将数据向上移动一个位置。
F[偏移后的数据 (向上移动)]: 表示移动后的数据,其中最后一个值为 NaN,其他值向上移动。
G[原始数据]: 代表原始的时间序列数据。
H{shift(freq='D')}: 表示应用 shift(freq='D') 函数,将时间索引移动一天。
I[偏移后的数据 (时间索引移动)]: 表示移动后的数据,数据本身没有改变,但是对应的时间索引发生了变化。
shift() 函数是 Pandas 中处理时间序列数据的重要工具,它允许我们将数据在时间轴上进行偏移。 通过合理使用 periods、freq、axis 和 fill_value 参数,我们可以灵活地执行各种时间序列分析任务,例如计算变化率、创建滞后特征以及对齐不同频率的时间序列。掌握 shift() 函数的使用,将大大提高时间序列数据处理的效率。