2016-06-30 3 views
4

私はPythonの新機能で、条件付きで値をオフセットする方法に固執しています。私は、新しい列を作成するだけでシフト機能を使用することができました。しかし、これは関数では機能しないようです。レコードが条件を満たしていれば、Python offsetカラムの値が前のレコードの値となります

オリジナル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 

私は、レコードSPEED=0と以前SPEED_END=0に前のレコードSPEED値に変更する前のレコードBEGIN値とSPEED値に変更するBEGIN値を求めています。

したがって、上記の表には、次のようになります。私は別の多くのことを試してみた

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) 

begin_condNaNTrueであり、maskdf['BEGIN']の値を置き換えます。次に、ffillNaNの値を最後の有効な値である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

私はあなたに衝撃を与える2段階の解決方法を提案します。

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'] 
関連する問題