web-dev-qa-db-ja.com

pd.DataFrameを保存するときに寄木細工のdtypeを強制する方法は?

列のすべての値がnullであっても、寄木細工のファイルに_pd.DataFrame_列を指定された型として強制的にエンコードさせる方法はありますか?寄木細工のスキーマで「null」が自動的に割り当てられるという事実により、多くのファイルを単一の_dask.dataframe_にロードできません。

df.column_name = df.column_name.astype(sometype)を使用してpandas列をキャストしようとしても機能しませんでした。

なぜ私がこれを尋ねているのですか

多くの寄木細工のファイルを単一の_dask.dataframe_にロードしたい。すべてのファイルは、df.to_parquet(filename)を使用して、_pd.DataFrame_のインスタンスから生成されました。すべてのデータフレームには同じ列がありますが、特定の列にはnull値のみが含まれる場合があります。すべてのファイルを_dask.dataframe_にロードしようとすると(df = dd.read_parquet('*.parquet')を使用)、次のエラーが発生します。

_Schema in filename.parquet was different.
id: int64
text: string
[...]
some_column: double

vs

id: int64
text: string
[...]
some_column: null
_

問題を再現する手順

_import pandas as pd
import dask.dataframe as dd
a = pd.DataFrame(['1', '1'], columns=('value',))
b = pd.DataFrame([None, None], columns=('value',))
a.to_parquet('a.parquet')
b.to_parquet('b.parquet')
df = dd.read_parquet('*.parquet')  # Reads a and b
_

これは私に次を与えます:

_ValueError: Schema in path/to/b.parquet was different. 
value: null
__index_level_0__: int64
metadata
--------
{b'pandas': b'{"index_columns": ["__index_level_0__"], "column_indexes": [{"na'
            b'me": null, "field_name": null, "pandas_type": "unicode", "numpy_'
            b'type": "object", "metadata": {"encoding": "UTF-8"}}], "columns":'
            b' [{"name": "value", "field_name": "value", "pandas_type": "empty'
            b'", "numpy_type": "object", "metadata": null}, {"name": null, "fi'
            b'eld_name": "__index_level_0__", "pandas_type": "int64", "numpy_t'
            b'ype": "int64", "metadata": null}], "pandas_version": "0.22.0"}'}

vs

value: string
__index_level_0__: int64
metadata
--------
{b'pandas': b'{"index_columns": ["__index_level_0__"], "column_indexes": [{"na'
            b'me": null, "field_name": null, "pandas_type": "unicode", "numpy_'
            b'type": "object", "metadata": {"encoding": "UTF-8"}}], "columns":'
            b' [{"name": "value", "field_name": "value", "pandas_type": "unico'
            b'de", "numpy_type": "object", "metadata": null}, {"name": null, "'
            b'field_name": "__index_level_0__", "pandas_type": "int64", "numpy'
            b'_type": "int64", "metadata": null}], "pandas_version": "0.22.0"}'}
_

ある場合には_"pandas_type": "unicode"_があり、もう一方の場合には_"pandas_type": "empty"_があることに注意してください。

解決策を提供しなかった関連質問

11
HugoMailhot

代わりにfastparquetを使用すると、必要なチャットを実現できます

import pandas as pd
import dask.dataframe as dd
a = pd.DataFrame(['1', '1'], columns=('value',))
b = pd.DataFrame([None, None], columns=('value',))
a.to_parquet('a.parquet', object_encoding='int', engine='fastparquet')
b.to_parquet('b.parquet', object_encoding='int', engine='fastparquet')

dd.read_parquet('*.parquet').compute()

与える

   value
0    1.0
1    1.0
0    NaN
1    NaN
5
mdurant