2016-06-30 42 views
4

我是Python新品,並且堅持如何有條件地偏移值。當我只需要創建一個新列時,我已經成功地使用了shift功能。但是,這似乎並不適用於某個功能。如果記錄符合條件,Python偏移列值與以前的記錄值

原DF:

BEGIN SPEED SPEED_END 
322  28  0 
341  0  23 
496  5  1 
500  0  0 
775  0  0 
979  0  0 
1015 0  0 
1022 0  14 
1050 11  6 

我想BEGIN值改變以前的記錄BEGIN值和SPEED值改變以前的記錄SPEED值的記錄,其中SPEED=0和以前SPEED_END=0

所以上面的表格應該是:

BEGIN SPEED SPEED_END 
322  28  0 
322  28  23 
496  5  1 
500  0  0 
500  0  0 
500  0  0 
500  0  0 
500  0  14 
1050 11  6 

我已經嘗試了很多不同的東西。目前,我已經試過:

def cont(row,param): 
    if row['SPEED'] == 0 and row['SPEED_END'].shift(1) == 0: 
     val = row[param].shift(1) 
    else: 
     val = row[param] 
    return val 

df['BEGIN'] = df.apply(cont, param='BEGIN', axis=1) 

但是,這給我的錯誤:

AttributeError: ("'float' object has no attribute 'shift'", u'occurred at index 0')

任何建議都感激!

回答

5

您可以使用maskffill

begin_cond = (df['SPEED'] == 0) & (df['SPEED_END'].shift(1) == 0) 
df['BEGIN'] = df['BEGIN'].mask(begin_cond).ffill().astype(int) 

從本質上講,mask將取代df['BEGIN']值是在begin_condTrueNaN。然後,ffill將向前填充NaN值與df['BEGIN']中的上一個有效值。

輸出結果:

BEGIN SPEED SPEED_END 
0 322  28   0 
1 322  0   23 
2 496  5   1 
3 500  0   0 
4 500  0   0 
5 500  0   0 
6 500  0   0 
7 500  0   14 
8 1050  11   6 
+0

謝謝!這非常接近工作!我在原始文章中添加了更多細節和數據行。我需要它循環,如果它改變了BEGIN,然後如果下一條記錄也符合相同的條件,那麼更新那個BEGIN是以前更新的BEGIN。我希望這是有道理的。 – Amber

+0

我已經更新瞭解釋重複的答案。 – root

+0

完美的作品!非常感謝!! – Amber

0

我會提出一個兩步驟的解決方案,它會讓你震驚。

df['begin_temp'] = df.begin.shift(1) 
df['begin_shifted'] = df.ix[(df.SPEED== 0) | (df.SPEED_END== 0), 'begin_temp'] 

然後

df.ix[df.begin_shifted.isnull(),'begin_shifted'] = df.ix[df.begin_shifted.isnull(),'begin']