为什么我不能在pandas函数中应用shift?

时间:2015-02-06 18:57:15

标签: python algorithm pandas

我正在尝试构建一个使用.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'

为什么不直接拨打班次?我需要将它嵌入到一个函数中,以便沿轴1同时计算多个列。参见相关问题Ambiguous truth value with boolean logic

3 个答案:

答案 0 :(得分:2)

尝试将框架传递给函数,而不是使用apply(我不确定为什么apply不起作用,甚至是列式的):

def f(x):
    x.level1 
    return x.level1 + x.level1.shift(1)

f(frame)

返回:

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

答案 1 :(得分:1)

检查您尝试移动的值是否不是数组。然后,您需要将数组转换为序列。这样您就可以移动值。我遇到了同样的问题,现在我可以获取平移值了。

这是我的代码部分,供您参考。

X = grouped['Confirmed_day'].values
X_series=pd.Series(X)

X_lag1 = X_series.shift(1)

答案 2 :(得分:0)

我并没有完全跟随,但如果框架[' level1'] .shift(1)有效,那么我只能想象那个框架[' level1']不管你传入verticaladd函数是什么,都不是numpy.int64对象。可能需要查看你的类型。