データフレームの列の悪い値をNaNで置き換えたいのですが。
mydata = {'x' : [10, 50, 18, 32, 47, 20], 'y' : ['12', '11', 'N/A', '13', '15', 'N/A']}
df = pd.DataFrame(mydata)
df[df.y == 'N/A']['y'] = np.nan
しかし、最後の行は失敗し、dfのコピーを処理しているので警告を出します。それで、これを処理するための正しい方法は何ですか? ilocやixを使った解決策はたくさんありますが、ここではブール条件を使用する必要があります。
replace
を使うだけです:
In [106]:
df.replace('N/A',np.NaN)
Out[106]:
x y
0 10 12
1 50 11
2 18 NaN
3 32 13
4 47 15
5 20 NaN
あなたがしようとしているのはチェーンインデックスと呼ばれています: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
loc
を使用して、元のdFを確実に操作できます。
In [108]:
df.loc[df['y'] == 'N/A','y'] = np.nan
df
Out[108]:
x y
0 10 12
1 50 11
2 18 NaN
3 32 13
4 47 15
5 20 NaN
replace
を使用すると問題が解決するようですが、代わりの方法を提案したいと思います。 np.nanで文字列を置き換えるのではなく、列全体を適切にするために、列内の数値と一部の文字列値を混在させると問題が発生します。元の列はオブジェクト型のものである可能性が最も高いと思います
Name: y, dtype: object
本当に必要なのは、それを数値列にすることです(それは適切な型を持ち、かなり高速になります)。非数値の値はすべてNaNに置き換えられます。
したがって、良い変換コードは
pd.to_numeric(df['y'], errors='coerce')
errors='coerce'
を指定すると、数値に解析できない文字列をNaNにすることができます。列タイプは
Name: y, dtype: float64
あなたが置き換えることができます:
df['y'] = df['y'].replace({'N/A': np.nan})
inplace
のreplace
パラメーターにも注意してください。次のようなことができます。
df.replace({'N/A': np.nan}, inplace=True)
これにより、コピーを作成せずにdf内のすべてのインスタンスが置き換えられます。
同様に、空の文字列やNone値など、他の種類の未知の値に遭遇した場合は、次のようにします。
df['y'] = df['y'].replace({'': np.nan})
df['y'] = df['y'].replace({None: np.nan})
df.loc[df.y == 'N/A',['y']] = np.nan
これであなたの問題は解決します。二重[]を使用すると、DataFrameのコピーに取り組んでいます。修正できるようにするには、1回の呼び出しで正確な場所を指定する必要があります。
あなたはこれらのスニペットを試すことができます。
[16]:mydata = {'x':[10、50、18、32、47、20]、 'y':['12'、 '11'、 'N/A'、 [13]、[15]、[N/A]] [。] [17]:df = pd.DataFrame(mydata) [18]:[d] y [df.y == "N/A"] = np.nan Out [19]:df xy 0 10 12 1 50 11 2 18 NaN 3 32 13 4 47 15 5 20 NaN