127 votes

Quelles sont les différences entre plume et parquet?

Les deux sont des formats de stockage (disque) colonnaires utilisés dans les systèmes d'analyse de données. Les deux sont intégrés dans Apache Arrow (paquet pyarrow pour python) et sont conçus pour correspondre à Arrow en tant que couche d'analyse en mémoire colonnaire.

En quoi les deux formats diffèrent-ils?

Devriez-vous toujours privilégier Feather lors de travailler avec pandas quand c'est possible?

Quels sont les cas d'utilisation où feather est plus adapté que parquet et vice versa?


Annexe

J'ai trouvé quelques indications ici https://github.com/wesm/feather/issues/188, mais étant donné la jeunesse de ce projet, cela pourrait être un peu obsolète.

Il ne s'agit pas d'un test de vitesse sérieux car je viens de déverser et de charger un DataFrame entier pour vous donner une idée si vous n'avez jamais entendu parler des formats avant:

 # IPython    
import numpy as np
import pandas as pd
import pyarrow as pa
import pyarrow.feather as feather
import pyarrow.parquet as pq
import fastparquet as fp

df = pd.DataFrame({'one': [-1, np.nan, 2.5],
                   'two': ['foo', 'bar', 'baz'],
                   'three': [True, False, True]})

print("pandas df to disk ####################################################")
print('example_feather:')
%timeit feather.write_feather(df, 'example_feather')
# 2.62 ms ± 35.8 µs par boucle (moyenne ± écart type de 7 exécutions, 100 boucles chacune)
print('example_parquet:')
%timeit pq.write_table(pa.Table.from_pandas(df), 'example.parquet')
# 3.19 ms ± 51 µs par boucle (moyenne ± écart type de 7 exécutions, 100 boucles chacune)
print()

print("pour comparaison:")
print('example_pickle:')
%timeit df.to_pickle('example_pickle')
# 2.75 ms ± 18.8 µs par boucle (moyenne ± écart type de 7 exécutions, 100 boucles chacune)
print('example_fp_parquet:')
%timeit fp.write('example_fp_parquet', df)
# 7.06 ms ± 205 µs par boucle (moyenne ± écart type de 7 exécutions, 1 boucle chacune)
print('example_hdf:')
%timeit df.to_hdf('example_hdf', 'key_to_store', mode='w', table=True)
# 24.6 ms ± 4.45 ms par boucle (moyenne ± écart type de 7 exécutions, 100 boucles chacune)
print()

print("pandas df from disk ##################################################")
print('example_feather:')
%timeit feather.read_feather('example_feather')
# 969 µs ± 1.8 µs par boucle (moyenne ± écart type de 7 exécutions, 1000 boucles chacune)
print('example_parquet:')
%timeit pq.read_table('example.parquet').to_pandas()
# 1.9 ms ± 5.5 µs par boucle (moyenne ± écart type de 7 exécutions, 1000 boucles chacune)

print("pour comparaison:")
print('example_pickle:')
%timeit pd.read_pickle('example_pickle')
# 1.07 ms ± 6.21 µs par boucle (moyenne ± écart type de 7 exécutions, 1000 boucles chacune)
print('example_fp_parquet:')
%timeit fp.ParquetFile('example_fp_parquet').to_pandas()
# 4.53 ms ± 260 µs par boucle (moyenne ± écart type de 7 exécutions, 1 boucle chacune)
print('example_hdf:')
%timeit pd.read_hdf('example_hdf')
# 10 ms ± 43.4 µs par boucle (moyenne ± écart type de 7 exécutions, 100 boucles chacune)

# version pandas : 0.22.0
# version fastparquet : 0.1.3
# version numpy : 1.13.3
# version pandas : 0.22.0
# version pyarrow : 0.8.0
# sys.version: 3.6.3
# Exemple de DataFrame pris sur https://arrow.apache.org/docs/python/parquet.html

172voto

Wes McKinney Points 17545
  • Le format Parquet est conçu pour le stockage à long terme, tandis que Arrow est plus destiné au stockage à court terme ou éphémère (Arrow pourrait être plus adapté au stockage à long terme après la sortie de la version 1.0.0, car le format binaire sera alors stable)

  • Il est plus coûteux d'écrire dans Parquet que dans Feather car il comporte plus de couches de codage et compression. Feather est la mémoire colonnaire brute non modifiée d'Arrow. Nous pourrions probablement ajouter une compression simple à Feather à l'avenir.

  • En raison du codage par dictionnaire, du codage RLE et de la compression des pages de données, les fichiers Parquet sont souvent beaucoup plus petits que les fichiers Feather

  • Parquet est un format de stockage standard pour l'analyse pris en charge par de nombreux systèmes différents : Spark, Hive, Impala, divers services AWS, et à l'avenir par BigQuery, etc. Donc, si vous effectuez de l'analyse, Parquet est une bonne option en tant que format de stockage de référence pour une requête par plusieurs systèmes

Les performances que vous avez montrées seront très bruyantes car les données que vous avez lues et écrites sont très petites. Vous devriez essayer de compresser au moins 100 Mo ou plus de 1 Go de données pour obtenir des performances plus informatives, voir par exemple http://wesmckinney.com/blog/python-parquet-multithreading/

J'espère que cela vous aidera

0 votes

Merci beaucoup Wes! Si vous ajoutez une compression simple à Feather à l'avenir, serait-il possible de la rendre optionnelle? J'envisage Feather comme un format alternatif au json pour un stockage d'événements dans un système de traitement de flux avec des exigences de latence assez basses. Donc, pour ce cas d'utilisation, ma préoccupation principale serait principalement la vitesse, pas la taille de stockage.

4 votes

Oui, "non compressé" sera toujours une option.

1 votes

J'ai remarqué que votre fonction generate_floats dans votre code de benchmark ici wesmckinney.com/blog/python-parquet-update ne garantit pas les unique_values. Ils sont juste aléatoires. Avec n=100M, j'ai obtenu des doublons deux fois sur dix essais. Je le mentionne juste au cas où quelqu'un utilise cette fonction où l'unicité devrait être garantie.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X