環境
- Python 3.12.4
- pandas 2.2.3
はじめに
pandas.read_csv
で欠損値を含むbool列を読み込んだときの挙動が、自分の期待と異なる部分があったので、その挙動をまとめました。
bool列の場合
欠損値なし AND dtypes
引数を指定しない
In [262]: data1="""
...: count,flag
...: 1,true
...: 2,false
...: """
In [265]: df1 = pd.read_csv(io.StringIO(data1))
In [266]: df1
Out[266]:
count flag
0 1 True
1 2 False
In [267]: df1.dtypes
Out[267]:
count int64
flag bool
dtype: object
dtypeはbool
になりました。
欠損値あり AND dtypes
引数を指定しない
In [269]: data2="""
...: count,flag
...: 1,true
...: 2,
...: """
In [270]: df2 = pd.read_csv(io.StringIO(data2))
In [271]: df2
Out[271]:
count flag
0 1 True
1 2 NaN
In [272]: df2.dtypes
Out[272]:
count int64
flag object
dtype: object
dtypeはobject
になり、欠損値はNaN
でした。
欠損値あり AND dtypes
引数を指定する
dtypeにbool
を指定する
In [290]: df2_2 = pd.read_csv(io.StringIO(data2), dtype={"flag":"bool"})
---------------------------------------------------------------------------
ValueError: Bool column has NA values in column 1
dtypeがbool
は欠損値を含むことができないので、ValueError
が発生しました。
以下のpandas.Series()
を実行したときのように、欠損値はFalse
に変換されると期待していたのですが、そうではありませんでした。
In [350]: pd.Series([None, True], dtype="bool")
Out[350]:
0 False
1 True
dtype: bool
dtypeにboolean
を指定する
In [291]: df2_3 = pd.read_csv(io.StringIO(data2), dtype={"flag":"boolean"})
In [292]: df2_3
Out[292]:
count flag
0 1 True
1 2 <NA>
In [294]: df2_3.dtypes
Out[294]:
count int64
flag boolean
dtype: object
dtypeがboolean
ならば欠損値を含むことができるので、エラーは発生しませんでした。
int列の場合
bool列と同じような結果ですが、一応記載します。
欠損値あり AND dtypes
引数を指定しない
In [304]: data3="""
...: count,count2
...: 1,10
...: 2,
...: """
In [305]: df3_1 = pd.read_csv(io.StringIO(data3))
In [306]: df3_1
Out[306]:
count count2
0 1 10.0
1 2 NaN
In [308]: df3_1.dtypes
Out[308]:
count int64
count2 float64
dtype: object
欠損値あり AND dtypes
引数を指定する
dtypeにint64
を指定する
In [309]: df3_2 = pd.read_csv(io.StringIO(data3), dtype={"count2":"int64"})
---------------------------------------------------------------------------
...
File parsers.pyx:1226, in pandas._libs.parsers.TextReader._convert_with_dtype()
ValueError: Integer column has NA values in column 1
dtypeにInt64
を指定する
In [310]: df3_3 = pd.read_csv(io.StringIO(data3), dtype={"count2":"Int64"})
In [311]: df3_3
Out[311]:
count count2
0 1 10
1 2 <NA>
In [312]: df3_3.dtypes
Out[312]:
count int64
count2 Int64
dtype: object
まとめ
- 欠損値を含むbool列には、dtypeに
boolean
を指定しましょう - 欠損値を含むint列には、dtypeに
Int64
を指定しましょう