環境
- Python 3.12.1
- panda 2.2.2
はじめに
pandas.Sereis.mapを使ったら、pandas.NA
がnumpy.nan
に変換されるときがありました。
実際に試して、どう変換されるかを確認しました。
結果
pd.NA
を含む場合
dtypeがInt64
In [51]: s2 = pd.Series([1, pd.NA],dtype="Int64")
In [52]: s2
Out[52]:
0 1
1 <NA>
dtype: Int64
In [53]: s2.map(lambda e: e)
Out[53]:
0 1.0
1 NaN
dtype: float64
pd.NA
がnp.nan
に変わりました。またdtypeがInt64
からfloat64
に変わりました。int64
でなくfloat64
に変わったのは、np.nan
の型がfloatだからでしょう。
dtypeがstring
In [54]: s3 = pd.Series(["a",pd.NA],dtype="string")
In [55]: s3
Out[55]:
0 a
1 <NA>
dtype: string
In [56]: s3.map(lambda e: e)
Out[56]:
0 a
1 <NA>
dtype: object
pd.NA
はそのままの値でした。しかし、dtype
がstring
からobject
に変わりました。
pd.NA
を含まない場合
dtypeがInt64
In [60]: s4 = pd.Series([1,2],dtype="Int64")
In [62]: s4
Out[62]:
0 1
1 2
dtype: Int64
In [61]: s4.map(lambda e: e)
Out[61]:
0 1
1 2
dtype: int64
dtypeがInt64
からint64
に変わりました。
dtypeがstring
In [64]: s5 = pd.Series(["a","b"],dtype="string")
In [65]: s5
Out[65]:
0 a
1 b
dtype: string
In [66]: s5.map(lambda e: e)
Out[66]:
0 a
1 b
dtype: object
dtypeがstring
からobject
に変わりました。
分かったこと
Series.map
に挙動について分かったことです。
- pandas独自のdtypeがnumpy用のdtypeに変換されます。たとえば
Int64
がint64
に、string
がobject
に変換されます。 - dtypeが
float64
やint64
の列はpd.NA
を含められないので、pd.NA
はnp.nan
に変換されます。ただしnp.nan
はfloat型なので、pd.NA
を含むdtypeがInt64
の列はfloat64
に変換されます。 - dtypeが
object
の列はpd.NA
を含むことができるので、dtypeがstring
の列に含まれるpd.NA
はnp.nan
に変換されません。
補足
pandas 2.1とpandas2.2で挙動が異なるようです。今後のpandasバージョンアップで、挙動が変わるかもしれません。