Closed1
Pandasでparquetに書き出す際に全行がNullだと型情報がなくなることがある
ざっくりこんな話
PandasのDataFrameをparquetに保存する際に、特定の列の全行Null値の場合はparquet内でのデータ型がnullになってしまう。
(作成済みのDBへparquetをインポートする際にこういうことがあると型が変換できないとエラーが出て困ることがある)
例
検証DataFrame
こういったDataFrameを3分割してparquetに吐き出す。
In [1]: import pandas as pd
In [2]: import pyarrow as pa
In [3]: df = pd.Series(["2024-01-01", None, "2024-01-02", None, "2024-01-03", "2024-01-04", None, None, None]).astype("datetime64[us]").dt.date.to_frame()
In [4]: df
Out[4]:
0
0 2024-01-01 ┐
1 NaT ├─ 0.parquetに吐き出す (date32[Day]型になる)
2 2024-01-02 ┘
3 NaT ┐
4 2024-01-03 ├─ 1.parquetに吐き出す (date32[Day]型になる)
5 2024-01-04 ┘
6 NaT ┐
7 NaT ├─ 2.parquetに吐き出す (null型になる)
8 NaT ┘
正常ケース: parquet内のデータ型がdate32型になる
In [5]: df.iloc[0:3].to_parquet("/tmp/0.parquet")
In [6]: pa.parquet.read_table("/tmp/0.parquet")
Out[6]:
pyarrow.Table
0: date32[day]
----
0: [[2024-01-01,null,2024-01-02]]
In [7]: df.iloc[3:6].to_parquet("/tmp/1.parquet")
In [8]: pa.parquet.read_table("/tmp/1.parquet")
Out[8]:
pyarrow.Table
0: date32[day]
----
0: [[null,2024-01-03,2024-01-04]]
異常ケース: 全行NULL値だとparquetのデータ型がNULLになる
In [9]: df.iloc[6:9].to_parquet("/tmp/2.parquet")
In [10]: pa.parquet.read_table("/tmp/2.parquet")
Out[10]:
pyarrow.Table
0: null
----
0: [3 nulls]
対策
(pandasだけではどうにもならないのでpyarrowで直接キャストした)
In [11]: pa.parquet.write_table(
...: pa.Table.from_pandas(
...: df.iloc[6:9]
...: ).cast(
...: pa.schema([
...: pa.field("0", pa.date32())
...: ])
...: ),
...: "/tmp/2.parquet"
...: )
In [12]: pa.parquet.read_table("/tmp/2.parquet")
Out[12]:
pyarrow.Table
0: date32[day]
----
0: [[null,null,null]]
このスクラップは2024/02/09にクローズされました