回答:
.loc
ラベルベースのインデックス作成に使用:
df.loc[df.A==0, 'B'] = np.nan
df.A==0
式はインデックス行というブールシリーズを作成し、'B'
列を選択します。これを使用して、列のサブセットを変換することもできます。例:
df.loc[df.A==0, 'B'] = df.loc[df.A==0, 'B'] / 2
私はパンダの内部について十分に理解していないので、それが機能する理由を正確に知ることはできませんが、基本的な問題は、DataFrameへのインデックス付けが結果のコピーを返したり、元のオブジェクトのビューを返したりすることです。ここのドキュメントによると、この動作は基になるnumpy動作に依存します。([one] [two]ではなく)1回の操作ですべてにアクセスする方が、設定に役立つ可能性が高いことがわかりました。
以下は、高度なインデックス作成に関するパンダのドキュメントからの抜粋です。
このセクションでは、必要なものを正確に説明します。判明df.loc
(.IXは廃止されているように-以下の指摘が多くて)データフレームのダイシング/クールスライスのために使用することができます。そして。物をセットするのにも使えます。
df.loc[selection criteria, columns I want] = value
だからブレンの答えは、「すべての場所を見つけてdf.A == 0
、列B
を選択してそれを設定するnp.nan
」と言っています
loc[selection criteria, columns I want]
完全にあなたの心にこだわる...
pandas 0.20以降、ixは非推奨になりました。正しい方法はdf.locを使用することです
これが実際の例です
>>> import pandas as pd
>>> import numpy as np
>>> df = pd.DataFrame({"A":[0,1,0], "B":[2,0,5]}, columns=list('AB'))
>>> df.loc[df.A == 0, 'B'] = np.nan
>>> df
A B
0 0 NaN
1 1 0
2 0 NaN
>>>
DOCで説明したようにここで、.loc
主に基づいてラベルされるだけでなく、ブール配列で使用することができます。
したがって、上記で行っていることは、以下df.loc[row_index, column_index]
によって適用されます。
loc
ブール配列をマスクとして使用して、変更したい行のサブセットをパンダに伝えることができるという事実を利用するrow_index
loc
も、ラベルに基づいて'B'
おり、column_index
論理、条件、または一連のブール値を返す任意の演算を使用して、ブール値の配列を作成できます。上記の例では、rows
を含むものが必要です。その0
ために使用できますdf.A == 0
。以下の例でわかるように、これは一連のブール値を返します。
>>> df = pd.DataFrame({"A":[0,1,0], "B":[2,0,5]}, columns=list('AB'))
>>> df
A B
0 0 2
1 1 0
2 0 5
>>> df.A == 0
0 True
1 False
2 True
Name: A, dtype: bool
>>>
次に、上記のブール値の配列を使用して、必要な行を選択および変更します。
>>> df.loc[df.A == 0, 'B'] = np.nan
>>> df
A B
0 0 NaN
1 1 0
2 0 NaN
大幅な速度向上のために、NumPyのwhere関数を使用します。
ゼロがいくつかある100,000行の2列のDataFrameを作成します。
df = pd.DataFrame(np.random.randint(0,3, (100000,2)), columns=list('ab'))
numpy.where
df['b'] = np.where(df.a.values == 0, np.nan, df.b.values)
%timeit df['b'] = np.where(df.a.values == 0, np.nan, df.b.values)
685 µs ± 6.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit df.loc[df['a'] == 0, 'b'] = np.nan
3.11 ms ± 17.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Numpy where
は約4倍高速です
.values
でnp.where(df.a.values == 0, np.nan, df.b.values)
?np.where(df.a == 0, np.nan, df.b)
うまくいくように見えますか?
where
示されているようにNumPyを使用してください