为什么我不能在 pandas 函数中应用 shift?
Why can't I apply shift from within a pandas function?
我正在尝试构建一个使用 .shift() 的函数,但它给我一个错误。
考虑一下:
In [40]:
data={'level1':[20,19,20,21,25,29,30,31,30,29,31],
'level2': [10,10,20,20,20,10,10,20,20,10,10]}
index= pd.date_range('12/1/2014', periods=11)
frame=DataFrame(data, index=index)
frame
Out[40]:
level1 level2
2014-12-01 20 10
2014-12-02 19 10
2014-12-03 20 20
2014-12-04 21 20
2014-12-05 25 20
2014-12-06 29 10
2014-12-07 30 10
2014-12-08 31 20
2014-12-09 30 20
2014-12-10 29 10
2014-12-11 31 10
一个正常的函数工作正常。为了演示我使用直接和函数方法计算了两次相同的结果:
In [63]:
frame['horizontaladd1']=frame['level1']+frame['level2']#works
def horizontaladd(x):
test=x['level1']+x['level2']
return test
frame['horizontaladd2']=frame.apply(horizontaladd, axis=1)
frame
Out[63]:
level1 level2 horizontaladd1 horizontaladd2
2014-12-01 20 10 30 30
2014-12-02 19 10 29 29
2014-12-03 20 20 40 40
2014-12-04 21 20 41 41
2014-12-05 25 20 45 45
2014-12-06 29 10 39 39
2014-12-07 30 10 40 40
2014-12-08 31 20 51 51
2014-12-09 30 20 50 50
2014-12-10 29 10 39 39
2014-12-11 31 10 41 41
但是虽然直接应用 shift 有效,但在函数中它不起作用:
frame['verticaladd1']=frame['level1']+frame['level1'].shift(1)#works
def verticaladd(x):
test=x['level1']+x['level1'].shift(1)
return test
frame.apply(verticaladd)#error
结果
KeyError: ('level1', u'occurred at index level1')
我也尝试过应用到单个列,这在我看来更有意义,但没有成功:
def verticaladd2(x):
test=x-x.shift(1)
return test
frame['level1'].map(verticaladd2)#error, also with apply
错误:
AttributeError: 'numpy.int64' object has no attribute 'shift'
为什么不直接调用shift?我需要将它嵌入到函数中以同时沿轴 1 计算多列。请参阅相关问题
我并不完全跟随,但如果 frame['level1'].shift(1) 有效,那么我只能想象 frame['level1'] 不是 numpy.int64对象,而无论您传递给 verticaladd 函数的是什么。可能需要看看你的类型。
尝试将框架传递给函数,而不是使用 apply
(我不确定为什么 apply
不起作用,即使是按列):
def f(x):
x.level1
return x.level1 + x.level1.shift(1)
f(frame)
returns:
2014-12-01 NaN
2014-12-02 39
2014-12-03 39
2014-12-04 41
2014-12-05 46
2014-12-06 54
2014-12-07 59
2014-12-08 61
2014-12-09 61
2014-12-10 59
2014-12-11 60
Freq: D, Name: level1, dtype: float64
检查您尝试移动的值是否不是数组。然后你需要将数组转换为系列。有了这个,您将能够改变价值。我遇到了同样的问题,现在我可以得到移位值了。
这是我的部分代码,供大家参考。
X = grouped['Confirmed_day'].values
X_series=pd.Series(X)
X_lag1 = X_series.shift(1)
我正在尝试构建一个使用 .shift() 的函数,但它给我一个错误。 考虑一下:
In [40]:
data={'level1':[20,19,20,21,25,29,30,31,30,29,31],
'level2': [10,10,20,20,20,10,10,20,20,10,10]}
index= pd.date_range('12/1/2014', periods=11)
frame=DataFrame(data, index=index)
frame
Out[40]:
level1 level2
2014-12-01 20 10
2014-12-02 19 10
2014-12-03 20 20
2014-12-04 21 20
2014-12-05 25 20
2014-12-06 29 10
2014-12-07 30 10
2014-12-08 31 20
2014-12-09 30 20
2014-12-10 29 10
2014-12-11 31 10
一个正常的函数工作正常。为了演示我使用直接和函数方法计算了两次相同的结果:
In [63]:
frame['horizontaladd1']=frame['level1']+frame['level2']#works
def horizontaladd(x):
test=x['level1']+x['level2']
return test
frame['horizontaladd2']=frame.apply(horizontaladd, axis=1)
frame
Out[63]:
level1 level2 horizontaladd1 horizontaladd2
2014-12-01 20 10 30 30
2014-12-02 19 10 29 29
2014-12-03 20 20 40 40
2014-12-04 21 20 41 41
2014-12-05 25 20 45 45
2014-12-06 29 10 39 39
2014-12-07 30 10 40 40
2014-12-08 31 20 51 51
2014-12-09 30 20 50 50
2014-12-10 29 10 39 39
2014-12-11 31 10 41 41
但是虽然直接应用 shift 有效,但在函数中它不起作用:
frame['verticaladd1']=frame['level1']+frame['level1'].shift(1)#works
def verticaladd(x):
test=x['level1']+x['level1'].shift(1)
return test
frame.apply(verticaladd)#error
结果
KeyError: ('level1', u'occurred at index level1')
我也尝试过应用到单个列,这在我看来更有意义,但没有成功:
def verticaladd2(x):
test=x-x.shift(1)
return test
frame['level1'].map(verticaladd2)#error, also with apply
错误:
AttributeError: 'numpy.int64' object has no attribute 'shift'
为什么不直接调用shift?我需要将它嵌入到函数中以同时沿轴 1 计算多列。请参阅相关问题
我并不完全跟随,但如果 frame['level1'].shift(1) 有效,那么我只能想象 frame['level1'] 不是 numpy.int64对象,而无论您传递给 verticaladd 函数的是什么。可能需要看看你的类型。
尝试将框架传递给函数,而不是使用 apply
(我不确定为什么 apply
不起作用,即使是按列):
def f(x):
x.level1
return x.level1 + x.level1.shift(1)
f(frame)
returns:
2014-12-01 NaN
2014-12-02 39
2014-12-03 39
2014-12-04 41
2014-12-05 46
2014-12-06 54
2014-12-07 59
2014-12-08 61
2014-12-09 61
2014-12-10 59
2014-12-11 60
Freq: D, Name: level1, dtype: float64
检查您尝试移动的值是否不是数组。然后你需要将数组转换为系列。有了这个,您将能够改变价值。我遇到了同样的问题,现在我可以得到移位值了。
这是我的部分代码,供大家参考。
X = grouped['Confirmed_day'].values
X_series=pd.Series(X)
X_lag1 = X_series.shift(1)