อะไรคือความแตกต่างระหว่างขนนกและไม้ปาร์เก้?


95

ทั้งสองเป็นรูปแบบการจัดเก็บคอลัมน์ (ดิสก์ -)สำหรับใช้ในระบบวิเคราะห์ข้อมูล ทั้งสองอย่างรวมอยู่ในApache Arrow ( แพ็คเกจpyarrowสำหรับ python) และได้รับการออกแบบให้สอดคล้องกับArrowเป็นเลเยอร์การวิเคราะห์ในหน่วยความจำแบบคอลัมน์

ทั้งสองรูปแบบแตกต่างกันอย่างไร?

คุณควรชอบขนนกเมื่อทำงานกับหมีแพนด้าเมื่อเป็นไปได้หรือไม่?

อะไรคือกรณีการใช้งานที่ขนนกเหมาะสมกว่าไม้ปาร์เก้และในทางกลับกัน?


ภาคผนวก

ฉันพบคำแนะนำบางอย่างที่นี่https://github.com/wesm/feather/issues/188แต่เนื่องจากโครงการนี้อายุยังน้อยอาจล้าสมัยไปบ้าง

ไม่ใช่การทดสอบความเร็วที่จริงจังเพราะฉันแค่ทิ้งและโหลด Dataframe ทั้งหมด แต่เพื่อให้คุณประทับใจหากคุณไม่เคยได้ยินเกี่ยวกับรูปแบบมาก่อน:

 # 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 มีไว้สำหรับการจัดเก็บระยะสั้นหรือการจัดเก็บชั่วคราว (Arrow อาจเหมาะสำหรับการจัดเก็บระยะยาวมากกว่าหลังจากการเปิดตัว 1.0.0 เกิดขึ้นเนื่องจากรูปแบบไบนารีจะคงที่แล้ว)

  • ไม้ปาร์เก้มีราคาแพงกว่าในการเขียนมากกว่า Feather เนื่องจากมีการเข้ารหัสและการบีบอัดข้อมูลหลายชั้น Feather เป็นหน่วยความจำ Arrow คอลัมน์ดิบที่ไม่ได้ปรับเปลี่ยน เราอาจจะเพิ่มการบีบอัดแบบธรรมดาให้กับ Feather ในอนาคต

  • เนื่องจากการเข้ารหัสพจนานุกรมการเข้ารหัส RLE และการบีบอัดหน้าข้อมูลไฟล์ Parquet มักจะมีขนาดเล็กกว่าไฟล์ Feather มาก

  • Parquet เป็นรูปแบบการจัดเก็บมาตรฐานสำหรับการวิเคราะห์ที่ระบบต่างๆรองรับเช่น Spark, Hive, Impala, บริการต่างๆของ AWS ในอนาคตโดย BigQuery เป็นต้นดังนั้นหากคุณกำลังทำการวิเคราะห์ Parquet เป็นตัวเลือกที่ดีในการเป็นรูปแบบการจัดเก็บข้อมูลอ้างอิง สอบถามโดยหลายระบบ

เกณฑ์มาตรฐานที่คุณแสดงจะมีเสียงดังมากเนื่องจากข้อมูลที่คุณอ่านและเขียนมีขนาดเล็กมาก คุณควรลองบีบอัดข้อมูลอย่างน้อย 100MB หรือสูงกว่า 1GB เพื่อให้ได้มาตรฐานข้อมูลเพิ่มเติมโปรดดูเช่นhttp://wesmckinney.com/blog/python-parquet-multithreading/

หวังว่านี่จะช่วยได้


3
ใช่ "ไม่บีบอัด" จะเป็นตัวเลือกเสมอ
Wes McKinney

1
ผมสังเกตเห็นว่าคุณgenerate_floatsฟังก์ชั่นในรหัสมาตรฐานของคุณที่นี่wesmckinney.com/blog/python-parquet-updateunique_valuesไม่รับประกัน พวกเขาเป็นเพียงการสุ่ม ด้วย n = 100M ฉันมีการทำซ้ำสองในสิบรัน เพียงแค่กล่าวถึงในกรณีที่มีผู้ใช้ฟังก์ชันนี้ซึ่งควรรับประกันความเป็นเอกลักษณ์
Darkonaut

1
@Darkonaut แค่สงสัยว่า ... การบีบอัดส่งผลให้มีขนาดเล็กลงดังนั้นมันจะเร็วกว่าที่จะอ่านลงในหน่วยความจำ อาจเป็นไปได้ว่าการประมวลผลพิเศษเนื่องจากการบีบอัด / คลายการบีบอัดจะยังคงเร็วกว่าการอ่านไบต์เพิ่มเติม หรือคุณมีสถานการณ์ที่ฉันคิดไม่ถึง?
PascalVKooten

2
HDF5 มีขนาดทั่วไปและมีน้ำหนักมาก ...
ivo Welch

4
@WesMcKinney ฉันสังเกตเห็นคำตอบของคุณเขียนย้อนกลับไปในปี 2018 หลังจากผ่านไป 2.3 ปีคุณยังคิดว่า Arrow (ขนนก) ไม่ดีสำหรับการจัดเก็บระยะยาว (โดยเปรียบเทียบกับไม้ปาร์เก้)? มีเหตุผลเฉพาะหรือไม่? ชอบความมั่นคง? วิวัฒนาการรูปแบบ? หรือ?
HCSF
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.