MysqlDBで使用するPandasまたはNumpy NanをNoneに置き換える


127

MysqlDBを使用してmysqlデータベースにPandasデータフレーム(またはnumpy配列を使用できます)を書き込もうとしています。MysqlDBは 'nan'を理解していないようで、nanがフィールドリストにないことを示すエラーがデータベースからスローされます。「nan」をNoneTypeに変換する方法を見つける必要があります。

何か案は?


2
あなたはそれを返すにするパンダに変更することができます何の設定はありませんNoneのためNULLの代わりはnan
Nathan Hinchey

回答:


194

@bogatronにはそれが正しく、を使用whereできます。これはパンダでネイティブに実行できることは注目に値します。

df1 = df.where(pd.notnull(df), None)

注:これにより、すべての列のdtypeがに変更されobjectます。

例:

In [1]: df = pd.DataFrame([1, np.nan])

In [2]: df
Out[2]: 
    0
0   1
1 NaN

In [3]: df1 = df.where(pd.notnull(df), None)

In [4]: df1
Out[4]: 
      0
0     1
1  None

注:dtypeデータフレームを再キャストして、すべてのデータ型を許可するには、を使用astypeしてから、DataFrame fillnaメソッドを使用します。

df1 = df.astype(object).replace(np.nan, 'None')

残念ながら、これもを使用することもreplaceこの(クローズされた)問題None確認することはできません。


余談ですが、ほとんどのユースケースではNaNをNoneに置き換える必要がないことに注意してください。パンダのNaNとNoneの違いについては、この質問を参照してください。。

ただし、この特定のケースでは、あなたがそうしているようです(少なくともこの回答の時点では)。



1
FWIW ..これにより、列のdtypeもオブジェクトに変更されます。おそらく気にしません
Jeff

@ジェフリンクをありがとう、奇妙なことに私はそれ以前にそれを見つけることができませんでした!私はそれがNoneを許可するためにdtypeを変更する必要があると考えました、間違いなく言及する価値があります!
アンディヘイデン2013年

np.nan文字列に変換されないようにするためにDjangoで挿入する前に使用すると便利です"nan"
shadi

有用な警告。既にあるカラムだけをループすることは理にかなってdtypeobject、それらのためにそれを行うと、必要に応じて、異なる他の種類を扱います。理想的にfillna(None)は素晴らしいでしょう。
Vishal 2018


17

あなたは置き換えることができnanNone、あなたのnumpyの配列に:

>>> x = np.array([1, np.nan, 3])
>>> y = np.where(np.isnan(x), None, x)
>>> print y
[1.0 None 3.0]
>>> print type(y[1])
<type 'NoneType'>

2
唯一の潜在的な懸念は変更されdtypex.dtypeされてdtype('float64')いる間、y.dtypeですdtype('object')
Jaime


4

@Andy Haydenの回答への追加:

DataFrame.maskはの反対の双子なので、DataFrame.where署名はまったく同じですが、意味が逆になります。

  • DataFrame.where条件がFalseである値置き換える場合に役立ちます。
  • DataFrame.mask条件がTrueである値置き換えるために使用されます。

したがって、この質問では、使用df.mask(df.isna(), other=None, inplace=True)する方が直感的かもしれません。


2

もう1つの追加:複数を置き換え、列の型をオブジェクトから浮動小数点に変換するときは注意してください。がにNone戻らないことを確実にしたい場合はnp.NaN、を使用して@ andy-haydenの提案を適用してくださいpd.where。どのようにして置換が「間違っている」かを示す図:

In [1]: import pandas as pd

In [2]: import numpy as np

In [3]: df = pd.DataFrame({"a": [1, np.NAN, np.inf]})

In [4]: df
Out[4]:
     a
0  1.0
1  NaN
2  inf

In [5]: df.replace({np.NAN: None})
Out[5]:
      a
0     1
1  None
2   inf

In [6]: df.replace({np.NAN: None, np.inf: None})
Out[6]:
     a
0  1.0
1  NaN
2  NaN

In [7]: df.where((pd.notnull(df)), None).replace({np.inf: None})
Out[7]:
     a
0  1.0
1  NaN
2  NaN

これを追加していただきありがとうございます。ドキュメントをもう一度見てみると、まだこの動作を理解できません。とにかく、これはさらに別のチェーンで回避できます.replace({np.nan: None})
EliadL

1
はい、別のを追加して終了できますreplace({np.nan: None})。の置き換え時の潜在的な落とし穴を指摘するために、私のコメントが追加されましたnp.nan。上記は確かに少し私をつまずかせました!
gaatjeniksaan

1

かなり古いですが、私はまったく同じ問題に遭遇しました。これを試してください:

df['col_replaced'] = df['col_with_npnans'].apply(lambda x: None if np.isnan(x) else x)

Noneがnan(
pandas
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.