2016-10-31 10 views
6

列が文字列の値を変更するたびにデータフレームの行にフラグを付けるにはどうすればよいですか?Pandas "diff()" with string

例:

入力

ColumnA ColumnB 
1   Blue 
2   Blue 
3   Red 
4   Red 
5   Yellow 


# diff won't work here with strings.... only works in numerical values 
dataframe['changed'] = dataframe['ColumnB'].diff()   


ColumnA ColumnB  changed 
1   Blue   0 
2   Blue   0 
3   Red   1 
4   Red   0 
5   Yellow  1 
+0

パフォーマンスノートを:単に 'np.bool'タイプの代わりに整数を使用する方がよいかもしれません。 'np.bool'は1バイトを使います。私はあなたが 'np.int8'を使うことができると思いますが、デフォルトでは' np.int64'や 'np.int64'(システム上のC言語が何であっても)が使われていると思います... –

答えて

7

私が代わりに実際の!=比較を使用してのneとのより良いパフォーマンスを得る:

df['changed'] = df['ColumnB'].ne(df['ColumnB'].shift().bfill()).astype(int) 

タイミング

を次のセットアップを使用して、より大きなデータフレームを作成します。

df = pd.concat([df]*10**5, ignore_index=True) 

私は、次のタイミングを取得:

%timeit df['ColumnB'].ne(df['ColumnB'].shift().bfill()).astype(int) 
10 loops, best of 3: 38.1 ms per loop 

%timeit (df.ColumnB != df.ColumnB.shift()).astype(int) 
10 loops, best of 3: 77.7 ms per loop 

%timeit df['ColumnB'] == df['ColumnB'].shift(1).fillna(df['ColumnB']) 
10 loops, best of 3: 99.6 ms per loop 

%timeit (df.ColumnB.ne(df.ColumnB.shift())).astype(int) 
10 loops, best of 3: 19.3 ms per loop 
+1

'(df.ColumnB.ne(df.ColumnB.shift())).statype(int)'のタイミングを追加できますか? – jezrael

+0

@jezrael:タイミングを追加しました。 'ix'を使って最初の行を0にすると、タイミングに〜1msが追加されるので、そのように最速に見えます。 – root

4

使用.shiftと比較:

dataframe['changed'] = dataframe['ColumnB'] == dataframe['ColumnB'].shift(1).fillna(dataframe['ColumnB']) 
+0

とてもきれいな答え – guilhermecgs

4

私の作品は、NaNが無いため値の前0を交換し、shiftと比較:

df['diff'] = (df.ColumnB != df.ColumnB.shift()).astype(int) 
df.ix[0,'diff'] = 0 
print (df) 
    ColumnA ColumnB diff 
0  1 Blue  0 
1  2 Blue  0 
2  3  Red  1 
3  4  Red  0 
4  5 Yellow  1 
別の答えの timingsによって

編集 - 最速はneを使用している:

df['diff'] = (df.ColumnB.ne(df.ColumnB.shift())).astype(int) 
df.ix[0,'diff'] = 0 
+1

私は、このアプローチと '!='を使うだけでパフォーマンスに違いはありますか? –

+1

@ juanpa.arrivillaga - はい、ありがとうございます。 – jezrael