列df
のデータフレームx
があり、これを疑似コードで使用してy
の値に基づいて列x
を作成する場合:
if df['x'] <-2 then df['y'] = 1
else if df['x'] > 2 then df['y']= -1
else df['y'] = 0
どうすればこれを達成できますか?私が想定し np.where
がこれを行う最良の方法ですが、正しくコーディングする方法がわかりません。
1つの簡単な方法は、最初にデフォルト値を割り当ててから、2つのloc
呼び出しを実行することです。
In [66]:
df = pd.DataFrame({'x':[0,-3,5,-1,1]})
df
Out[66]:
x
0 0
1 -3
2 5
3 -1
4 1
In [69]:
df['y'] = 0
df.loc[df['x'] < -2, 'y'] = 1
df.loc[df['x'] > 2, 'y'] = -1
df
Out[69]:
x y
0 0 0
1 -3 1
2 5 -1
3 -1 0
4 1 0
np.where
を使用する場合は、ネストされたnp.where
を使用できます。
In [77]:
df['y'] = np.where(df['x'] < -2 , 1, np.where(df['x'] > 2, -1, 0))
df
Out[77]:
x y
0 0 0
1 -3 1
2 5 -1
3 -1 0
4 1 0
したがって、ここでは、xが-2より小さい場合の最初の条件を定義し、1を返します。次に、xが2より大きく、-1を返す他の条件をテストする別のnp.where
があります。それ以外の場合は0を返します。
タイミング
In [79]:
%timeit df['y'] = np.where(df['x'] < -2 , 1, np.where(df['x'] > 2, -1, 0))
1000 loops, best of 3: 1.79 ms per loop
In [81]:
%%timeit
df['y'] = 0
df.loc[df['x'] < -2, 'y'] = 1
df.loc[df['x'] > 2, 'y'] = -1
100 loops, best of 3: 3.27 ms per loop
したがって、このサンプルデータセットの場合、np.where
メソッドは2倍高速です。
これはpd.cut
の良い使用例で、範囲を定義し、それらに基づいてranges
を割り当てることができますlabels
:
df['y'] = pd.cut(df['x'], [-np.inf, -2, 2, np.inf], labels=[1, 0, -1], right=False)
出力
x y
0 0 0
1 -3 1
2 5 -1
3 -1 0
4 1 0