为何DataFrame.shift()的axis参数无效果?
嘿,这个问题其实是因为你混淆了shift()方法两种不同的使用场景——基于整数周期的移位和基于时间偏移的移位,这两种场景下axis参数的作用完全不同:
1. 时间偏移下axis参数被忽略的原因
当你传入时间偏移对象(比如pd.DateOffset(days=2)、pd.Timedelta(days=2))作为shift()的第一个参数时,这个操作的设计目标就是偏移行索引中的时间标签,本质是对时间索引进行平移,而不是移动数据的位置。这时候axis参数会被直接忽略,不管你设axis=0还是axis=1,都会只偏移行索引,所以你得到的结果是一样的。
举个例子,假设你的DataFrame是这样的:
import pandas as pd df = pd.DataFrame( {'Val': [10, 20, 30, 40]}, index=pd.date_range('2024-01-01', periods=4) )
当你执行df.shift(pd.DateOffset(days=2))或者df.shift(pd.DateOffset(days=2), axis=1),结果都是行索引被往后移2天,Val列的数据跟着索引走,空出来的位置补NaN。
2. 实现你期望的“索引不变,Val列移位”的方法
如果你想要保持行索引(Date)不变,只移动Val列的数据,你需要用整数周期的移位,这里你之前对axis=1的理解也有点偏差,具体方法如下:
方式1:直接对列执行行方向移位
最直观的方式是单独对Val列使用整数periods,默认就是行方向移位(上下移动数据),索引会保持不变:
# 把Val列的数据向下移2行,原索引保留,空值补NaN df['Val_shifted'] = df['Val'].shift(periods=2)
方式2:对整个DataFrame做行方向移位
如果你要对所有列都做行方向移位,直接用整数periods,默认axis=0就是行方向移位,索引依然保持原有的Date:
# 所有列的数据向下移2行,索引不变 df_shifted = df.shift(periods=2)
这里要额外说明:axis=1的作用是列之间的横向移位(比如把Val列的数据移到新的列位置),而不是你理解的“保持索引不变移列数据”。比如df.shift(periods=1, axis=1)会生成新列来承接Val的数据,原Val列补NaN,但索引还是原来的Date,这和你想要的效果是不一样的哦。
总结一下
- 用时间偏移对象调用
shift():专门用来偏移时间类型的行索引,axis参数无效 - 用整数periods调用
shift():axis=0(默认)是行方向移位(数据上下移,索引不变);axis=1是列方向移位(数据左右移,索引不变)
内容的提问来源于stack exchange,提问作者feetwet

