Existe-t-il un moyen de forcer un fichier parquet à coder une colonne pd.DataFrame
sous un type donné, même si toutes les valeurs de la colonne sont nulles? Le fait que parquet affecte automatiquement "null" dans son schéma m'empêche de charger plusieurs fichiers dans un seul dask.dataframe
.
Essayer de lancer la colonne pandas en utilisant df.column_name = df.column_name.astype(sometype)
n'a pas fonctionné.
Pourquoi je demande ceci
Je veux charger plusieurs fichiers de parquet dans un seul dask.dataframe
. Tous les fichiers ont été générés à partir de autant d'instances de pd.DataFrame
, à l'aide de df.to_parquet(filename)
. Toutes les images ont les mêmes colonnes, mais pour certaines, une colonne donnée peut contenir uniquement des valeurs NULL. En essayant de charger tous les fichiers dans le dask.dataframe
(en utilisant df = dd.read_parquet('*.parquet')
, j'obtiens le message d'erreur suivant:
Schema in filename.parquet was different.
id: int64
text: string
[...]
some_column: double
vs
id: int64
text: string
[...]
some_column: null
Procédure pour reproduire mon problème
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
Cela me donne ce qui suit:
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"}'}
Remarquez comment dans un cas nous avons "pandas_type": "unicode"
et dans l'autre nous avons "pandas_type": "empty"
.
Questions connexes qui ne m'ont pas apporté de solution
Si vous utilisez plutôt fastparquet
, vous pouvez réaliser le chat de votre choix
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()
donne
value
0 1.0
1 1.0
0 NaN
1 NaN