Quali sono le differenze tra piuma e parquet?


95

Entrambi sono formati di archiviazione colonnari (su disco) da utilizzare nei sistemi di analisi dei dati. Entrambi sono integrati in Apache Arrow ( pacchetto pyarrow per python) e sono progettati per corrispondere ad Arrow come livello di analisi in memoria colonnare.

In cosa differiscono entrambi i formati?

Dovresti sempre preferire la piuma quando lavori con i panda, quando possibile?

Quali sono i casi d'uso in cui la piuma è più adatta del parquet e viceversa?


Appendice

Ho trovato alcuni suggerimenti qui https://github.com/wesm/feather/issues/188 , ma data la giovane età di questo progetto, forse è un po 'antiquato.

Non è un test di velocità serio perché sto solo scaricando e caricando un intero Dataframe, ma per darti un'impressione se non hai mai sentito parlare dei formati prima:

 # 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 per loop (mean ± std. dev. of 7 runs, 100 loops each)
print('example_parquet:')
%timeit pq.write_table(pa.Table.from_pandas(df), 'example.parquet')
# 3.19 ms ± 51 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
print()

print("for comparison:")
print('example_pickle:')
%timeit df.to_pickle('example_pickle')
# 2.75 ms ± 18.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
print('example_fp_parquet:')
%timeit fp.write('example_fp_parquet', df)
# 7.06 ms ± 205 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
print('example_hdf:')
%timeit df.to_hdf('example_hdf', 'key_to_store', mode='w', table=True)
# 24.6 ms ± 4.45 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
print()

print("pandas df from disk ##################################################")
print('example_feather:')
%timeit feather.read_feather('example_feather')
# 969 µs ± 1.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
print('example_parquet:')
%timeit pq.read_table('example.parquet').to_pandas()
# 1.9 ms ± 5.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

print("for comparison:")
print('example_pickle:')
%timeit pd.read_pickle('example_pickle')
# 1.07 ms ± 6.21 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
print('example_fp_parquet:')
%timeit fp.ParquetFile('example_fp_parquet').to_pandas()
# 4.53 ms ± 260 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
print('example_hdf:')
%timeit pd.read_hdf('example_hdf')
# 10 ms ± 43.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

# pandas version: 0.22.0
# fastparquet version: 0.1.3
# numpy version: 1.13.3
# pandas version: 0.22.0
# pyarrow version: 0.8.0
# sys.version: 3.6.3
# example Dataframe taken from https://arrow.apache.org/docs/python/parquet.html

Risposte:


136
  • Il formato Parquet è progettato per l'archiviazione a lungo termine, dove Arrow è più inteso per l'archiviazione a breve termine o temporanea (Arrow potrebbe essere più adatto per l'archiviazione a lungo termine dopo la versione 1.0.0, poiché il formato binario sarà stabile allora)

  • Parquet è più costoso da scrivere rispetto a Feather in quanto presenta più livelli di codifica e compressione. La piuma è una memoria Arrow colonnare grezza non modificata. Probabilmente in futuro aggiungeremo una semplice compressione a Feather.

  • A causa della codifica del dizionario, della codifica RLE e della compressione della pagina dati, i file Parquet saranno spesso molto più piccoli dei file Feather

  • Parquet è un formato di archiviazione standard per l'analisi supportato da molti sistemi diversi: Spark, Hive, Impala, vari servizi AWS, in futuro da BigQuery, ecc. Quindi, se stai facendo analisi, Parquet è una buona opzione come formato di archiviazione di riferimento per query da più sistemi

I benchmark che hai mostrato saranno molto rumorosi poiché i dati che hai letto e scritto sono molto piccoli. Dovresti provare a comprimere almeno 100 MB o più di 1 GB di dati per ottenere benchmark più informativi, vedi ad esempio http://wesmckinney.com/blog/python-parquet-multithreading/

Spero che sia di aiuto


3
Sì, "non compresso" sarà sempre un'opzione
Wes McKinney

1
Ho notato che la tua generate_floatsfunzione nel codice di benchmark qui wesmckinney.com/blog/python-parquet-update non garantisce unique_values. Sono solo casuali. Con n = 100M ho duplicato due corse su dieci. Solo menzionando nel caso in cui qualcuno usi questa funzione, dove l'unicità dovrebbe essere garantita.
Darkonaut

1
@Darkonaut mi chiedevo solo ... la compressione risulta in dimensioni più piccole, quindi sarebbe più veloce leggerlo in memoria. Potrebbe essere che l'elaborazione extra dovuta alla compressione / decompressione sarà ancora più veloce rispetto alla lettura di più byte. O hai una situazione a cui non penso?
PascalVKooten

2
HDF5 è più generale e pesante ... anche molto più lento la maggior parte del tempo.
ivo Welch

4
@WesMcKinney Ho notato che la tua risposta è stata scritta nel 2018. Dopo 2,3 anni, pensi ancora che Arrow (piuma) non sia adatto per la conservazione a lungo termine (rispetto a Parquet)? C'è una ragione specifica? Ti piace la stabilità? evoluzione del formato? o?
HCSF
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.