羽と寄木細工の違いは何ですか?


95

どちらも、データ分析システムで使用するための柱状(ディスク)ストレージ形式です。両方が内に一体化されているApacheの矢印pyarrowのPython用のパッケージ)とに対応するように設計されている矢印柱状インメモリ分析層として。

両方のフォーマットはどのように異なりますか?

可能であれば、パンダを扱うときは常に羽を好むべきですか?

寄木細工よりもが適している、またはその逆のユースケースは何ですか?


付録

https://github.com/wesm/feather/issues/188でいくつかのヒントを見つけましたが、このプロジェクトの年齢が若いことを考えると、おそらく少し時代遅れです。

データフレーム全体をダンプしてロードしているだけなので、深刻な速度テストではありませんが、これまでフォーマットについて聞いたことがない場合は、印象を与えるためです。

 # 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

回答:


136
  • 寄木細工の形式は長期保存用に設計されており、Arrowは短期または一時的な保存を目的としています(バイナリ形式は安定しているため、1.0.0リリース後の長期保存にはArrowの方が適している場合があります)

  • Parquetは、エンコードと圧縮のレイヤーが多いため、Featherよりも作成コストが高くなります。フェザーは、変更されていない生の円柱状の矢印メモリです。将来的には、Featherに単純な圧縮を追加する予定です。

  • ディクショナリエンコーディング、RLEエンコーディング、およびデータページ圧縮により、ParquetファイルはFeatherファイルよりもはるかに小さいことがよくあります。

  • Parquetは、Spark、Hive、Impala、さまざまなAWSサービス、将来的にはBigQueryなど、さまざまなシステムでサポートされる分析の標準ストレージ形式です。したがって、分析を行う場合、Parquetはの参照ストレージ形式として適したオプションです。複数のシステムによるクエリ

読み取りと書き込みのデータが非常に小さいため、表示したベンチマークは非常にノイズが多くなります。より有益なベンチマークを取得するには、少なくとも100MB以上の1GBのデータを圧縮してみてください。たとえば、http: //wesmckinney.com/blog/python-parquet-multithreading/を参照してください。

お役に立てれば


3
はい、「非圧縮」は常にオプションです
WesMcKinney18年

1
generate_floatsここwesmckinney.com/blog/python-parquet-updateのベンチマークコードの関数は保証されないことに気づきましたunique_values。それらはただランダムです。n = 100Mの場合、10回の実行のうち2回の重複が発生しました。誰かがこの関数を使用して一意性を保証する必要がある場合に備えて言及するだけです。
Darkonaut 2018年

1
@Darkonautは疑問に思っています...圧縮するとサイズが小さくなるため、メモリに読み込むのが速くなります。圧縮/解凍による余分な処理は、より多くのバイトを読み取る必要がある場合よりも高速である可能性があります。それとも私が考えていない状況がありますか?
PascalVKooten

2
HDF5はより一般的で重いです...また、ほとんどの場合、はるかに低速です。
ウェルチIVO

4
@WesMcKinneyあなたの答えが2018年に書き戻されていることに気づきました。2。3年経った今でも、Arrow(羽)は(Parquetと比較して)長期保管には適していないと思いますか?特定の理由はありますか?安定性が好きですか?フォーマットの進化?または?
HCSF
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.