pandas shift中freq='infer'的作用是什么?与freq='D'有什么区别?

2 投票
1 回答
47 浏览
提问于 2025-04-13 16:17

我没有看到在.shift()中,freq的区别是什么。

df = pd.DataFrame({"Col1": [10, 20, 15, 30, 45],
                   "Col2": [13, 23, 18, 33, 48],
                   "Col3": [17, 27, 22, 37, 52]},
                  index=pd.date_range("2020-01-01", "2020-01-05"))

df.shift(periods=2, freq="infer")

            Col1  Col2  Col3
2020-01-03    10    13    17
2020-01-04    20    23    27
2020-01-05    15    18    22
2020-01-06    30    33    37
2020-01-07    45    48    52

返回的结果和

df.shift(periods=2, freq="d")

            Col1  Col2  Col3
2020-01-03    10    13    17
2020-01-04    20    23    27
2020-01-05    15    18    22
2020-01-06    30    33    37
2020-01-07    45    48    52

有没有人能解释一下freq='infer'这个参数的作用是什么?

1 个回答

2

freq='infer'的意思是频率是根据索引的元数据推断出来的。

freq 是一个可选项,可以是 DateOffset、tseries.offsets、timedelta 或字符串。

这个选项用来指定时间序列模块中的偏移量或时间规则(比如说‘EOM’)。

如果指定了 freq,那么索引的值会被移动,但数据不会重新对齐。也就是说,如果你想在移动时扩展索引并保留原始数据,就要使用 freq。如果 freq 被指定为“infer”,那么它会从索引的 freq 或 inferred_freq 属性中推断出来。如果这两个属性都不存在,就会抛出一个 ValueError 错误。

假设这个例子中的索引频率是两周:

df = pd.DataFrame({"Col1": [10, 20, 15, 30, 45],
                   "Col2": [13, 23, 18, 33, 48],
                   "Col3": [17, 27, 22, 37, 52]},
                  index=pd.date_range("2020-01-01", periods=5, freq='2W'))

df.index
# DatetimeIndex(['2020-01-05', ..., '2020-03-01'], dtype='datetime64[ns]',
#               freq='2W-SUN')  # <- the important part

df.shift(periods=2, freq='infer') 将会移动 2 个周期的 2 周 = 4 周:

df.shift(periods=2, freq='infer')
            Col1  Col2  Col3
2020-02-02    10    13    17   # 4W after 2020-01-05
2020-02-16    20    23    27
2020-03-01    15    18    22
2020-03-15    30    33    37
2020-03-29    45    48    52   # 4W after 2020-03-01

相比之下,简单的 df.shift(periods=2) 只是移动了 2 行:

df.shift(periods=2)

            Col1  Col2  Col3
2020-01-05   NaN   NaN   NaN
2020-01-19   NaN   NaN   NaN
2020-02-02  10.0  13.0  17.0
2020-02-16  20.0  23.0  27.0
2020-03-01  15.0  18.0  22.0

在你的例子中,date_range 的默认频率是 D,所以这确实会产生相同的输出。我们把它改成 freq='3D'

df = pd.DataFrame({"Col1": [10, 20, 15, 30, 45],
                   "Col2": [13, 23, 18, 33, 48],
                   "Col3": [17, 27, 22, 37, 52]},
                  index=pd.date_range("2020-01-01", periods=5, freq='3D'))

# shift by 2 * D
df.shift(periods=2, freq='D')
            Col1  Col2  Col3
2020-01-03    10    13    17  # 2*1D after 2020-01-01
2020-01-05    20    23    27
2020-01-07    15    18    22
2020-01-09    30    33    37
2020-01-11    45    48    52

# shift by 2 * 3D = 6D
df.shift(periods=2, freq='infer')
            Col1  Col2  Col3
2020-01-07    10    13    17  # 2*3D after 2020-01-01
2020-01-10    20    23    27
2020-01-13    15    18    22
2020-01-16    30    33    37
2020-01-19    45    48    52

撰写回答