PythonでPandasの値をNone
に置き換える方法はありますか?
df.replace('pre', 'post')
を使用して値を別の値に置き換えることができますが、None
の値で置き換えたい場合、これを行うことはできません。
以下に例を示します。
df = DataFrame(['-',3,2,5,1,-5,-1,'-',9])
df.replace('-', 0)
成功した結果を返します。
しかし、
df.replace('-', None)
次の結果が返されます。
0
0 - // this isn't replaced
1 3
2 2
3 5
4 1
5 -5
6 -1
7 -1 // this is changed to `-1`...
8 9
なぜこのような奇妙な結果が返されるのですか?
このデータフレームをMySQLデータベースに注ぎたいので、NaN
値をデータフレームの要素に入れることができず、代わりにNone
を入れたいです。確かに、最初に'-'
をNaN
に変更してからNaN
をNone
に変換できますが、データフレームがこのようにひどい動作をする理由を知りたいです。
pandas 0.12.0 dev Python 2.7およびOS X 10.8でテスト済み。 PythonはOS Xにプリインストールされたバージョンであり、情報としてSciPy Superpackスクリプトを使用してpandasをインストールしました。
実際、pandasの後のバージョンでは、TypeErrorが発生します:
df.replace('-', None)
TypeError: If "to_replace" and "value" are both None then regex must be a mapping
リストまたは辞書を渡すことでそれを行うことができます:
In [11]: df.replace('-', df.replace(['-'], [None]) # or .replace('-', {0: None})
Out[11]:
0
0 None
1 3
2 2
3 5
4 1
5 -5
6 -1
7 None
8 9
ただし、なしではなくNaNを使用することをお勧めします。
In [12]: df.replace('-', np.nan)
Out[12]:
0
0 NaN
1 3
2 2
3 5
4 1
5 -5
6 -1
7 NaN
8 9
where
はおそらくあなたが探しているものです。そう
data=data.where(data=='-', None)
panda docs から:
where
[戻り] selfと同じ形状のオブジェクトで、対応するエントリがcondがTrueである場合はselfからのものであり、そうでない場合はotherからのものです。
replace
をdict
とともに使用するソリューションは、そのシンプルさと優雅さから好まれます。
df.replace({'-': None})
また、より多くの代替品を持つことができます:
df.replace({'-': None, 'None': None})
そして、大規模な代替品であっても、何が何によって代替されるかは常に明白で明確です-私の意見では、これは長いリストにとってははるかに困難です。
この投稿を進める前に、 NaNとNoneの違い を理解することが重要です。 1つはfloat型で、もう1つはオブジェクト型です。 Pandasは、これらの型の多くのメソッドをベクトル化できるため、スカラー型の操作により適しています。 PandasはNoneとNaNを一貫して処理しようとしますが、NumPyは処理できません。
私の提案( およびAndy's )は、NaNに固執することです。
na_values=['-']
CSV/Excelからこのデータを読み込んだ場合、良いニュースがあります。後続のステップとしてコードで修正を書く代わりに、データのロード中にルートでこれを無効にすることができます。
ほとんどのpd.read_*
関数( read_csv
や read_Excel
など)は、na_values
属性を受け入れます。
file.csv
A,B
-,1
3,-
2,-
5,3
1,-2
-5,4
-1,-1
-,0
9,0
ここで、-
文字をNaNに変換するには、次のようにします。
import pandas as pd
df = pd.read_csv('file.csv', na_values=['-'])
df
A B
0 NaN 1.0
1 3.0 NaN
2 2.0 NaN
3 5.0 3.0
4 1.0 -2.0
5 -5.0 4.0
6 -1.0 -1.0
7 NaN 0.0
8 9.0 0.0
他の関数/ファイル形式でも同様です。
追伸:v0.24 +では、列にNaNが含まれていても整数型を保持できます(はい、ケーキを食べて食べることについても話してください)。 dtype='Int32'
を指定できます
df = pd.read_csv('file.csv', na_values=['-'], dtype='Int32')
df
A B
0 NaN 1
1 3 NaN
2 2 NaN
3 5 3
4 1 -2
5 -5 4
6 -1 -1
7 NaN 0
8 9 0
df.dtypes
A Int32
B Int32
dtype: object
Dtypeは従来のint型ではなく... Nullable Integer Type。 他のオプションがあります。
pd.to_numeric
とerrors='coerce
数値データを扱う場合、より速い解決策は pd.to_numeric
をerrors='coerce'
引数とともに使用することです。これは無効な値(数値にキャストできない値)をNaNに強制します。
pd.to_numeric(df['A'], errors='coerce')
0 NaN
1 3.0
2 2.0
3 5.0
4 1.0
5 -5.0
6 -1.0
7 NaN
8 9.0
Name: A, dtype: float64
(nullable)整数dtypeを保持するには、次を使用します
pd.to_numeric(df['A'], errors='coerce').astype('Int32')
0 NaN
1 3
2 2
3 5
4 1
5 -5
6 -1
7 NaN
8 9
Name: A, dtype: Int32
複数の列を強制するには、apply
を使用します。
df[['A', 'B']].apply(pd.to_numeric, errors='coerce').astype('Int32')
A B
0 NaN 1
1 3 NaN
2 2 NaN
3 5 3
4 1 -2
5 -5 4
6 -1 -1
7 NaN 0
8 9 0
...そして結果を後に割り当てます。
詳細は this answer にあります。
df = pd.DataFrame(['-',3,2,5,1,-5,-1,'-',9])
df = df.where(df!='-', None)
ヌル値の設定は、np.nan
を使用して実行できます。
import numpy as np
df.replace('-', np.nan)
利点は、df.last_valid_index()
がこれらを無効として認識することです。