我有一个单列DataFrame(数据),按有序日期索引,我想创建第二个具有p列的DataFrame,并为每列分配一个移位的数据版本。即,我想在第一列中看到data.shift(1),在第二列中看到data.shift(2),依此类推。我的实现如下:
lagged_data = pd.DataFrame(index = data.index, columns=[i+1 for i in range(p)])
for i in range(p):
lagged_data.iloc[:,i] = data.shift(i+1)
但是,执行后仅更新第一列,而其他所有列均保留为np.nan。参见下面的结果(p = 3):
print(lagged_data.head())
1 2 3
Date
gen-75 NaN NaN NaN
feb-75 0.03 NaN NaN
mar-75 0.04 NaN NaN
apr-75 -0.04 NaN NaN
mag-75 0.04 NaN NaN
奇怪的是,通过在同一循环中再重复一次,可以正确填充ALL列。我真的不知道这种行为的原因,我也尝试通过这样做来创建副本
lagged_data.iloc[:,i] = data.shift(i+1).copy()
但这会提供与以前相同的结果
答案 0 :(得分:2)
您正在将数据框分配给系列。尽管这样做会带来结果,但您不应期望起作用。而是将一个系列分配给一个系列并使用pd.Series.shift
:
data = pd.DataFrame({'A': [1, 2, 3, 4, 5]})
lagged_data = pd.DataFrame(index=data.index, columns=[i+1 for i in range(3)])
for i in range(3):
lagged_data.iloc[:,i] = data.iloc[:, 0].shift(i + 1)
print(lagged_data)
# 1 2 3
# 0 NaN NaN NaN
# 1 1.0 NaN NaN
# 2 2.0 1.0 NaN
# 3 3.0 2.0 1.0
# 4 4.0 3.0 2.0
通知data
是pd.DataFrame
对象,而data.iloc[:, 0]
是pd.Series
对象。
pd.concat
(具有列表理解功能)在这种情况下,您可以将pd.concat
与列表理解结合使用,指定keys
参数和axis=1
:
res = pd.concat([data.iloc[:, 0].shift(i+1) for i in range(3)],
keys=list(range(1, 4)), axis=1)