Sự khác biệt giữa lông vũ và gỗ lát sàn là gì?


89

Cả hai đều là định dạng lưu trữ dạng cột (đĩa-) để sử dụng trong các hệ thống phân tích dữ liệu. Cả hai đều được tích hợp trong Apache Arrow ( gói pyarrow cho python) và được thiết kế để tương ứng với Arrow như một lớp phân tích trong bộ nhớ dạng cột.

Làm thế nào để cả hai định dạng khác nhau?

Bạn có nên luôn thích lông vũ khi làm việc với gấu trúc khi có thể?

Những trường hợp sử dụng nào mà lông vũ phù hợp hơn ván gỗ và ngược lại?


ruột thừa

Tôi đã tìm thấy một số gợi ý ở đây https://github.com/wesm/feather/issues/188 , nhưng với tuổi đời còn non trẻ của dự án này, nó có thể hơi lỗi thời.

Không phải là một bài kiểm tra tốc độ nghiêm trọng vì tôi chỉ kết xuất và tải toàn bộ Dataframe nhưng để cung cấp cho bạn một số ấn tượng nếu bạn chưa từng nghe đến các định dạng trước đây:

 # 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

Câu trả lời:


131
  • Định dạng Parquet được thiết kế để lưu trữ lâu dài, trong đó Arrow dành cho lưu trữ ngắn hạn hoặc tạm thời hơn (Arrow có thể phù hợp hơn để lưu trữ lâu dài sau khi bản 1.0.0 ra mắt, vì khi đó định dạng nhị phân sẽ ổn định)

  • Parquet đắt hơn để viết so với Feather vì nó có nhiều lớp mã hóa và nén hơn. Feather là bộ nhớ Arrow dạng cột thô chưa sửa đổi. Chúng tôi có thể sẽ thêm tính năng nén đơn giản cho Feather trong tương lai.

  • Do mã hóa từ điển, mã hóa RLE và nén trang dữ liệu, tệp Parquet thường sẽ nhỏ hơn nhiều so với tệp Feather

  • Parquet là định dạng lưu trữ chuẩn cho phân tích được hỗ trợ bởi nhiều hệ thống khác nhau: Spark, Hive, Impala, các dịch vụ AWS khác nhau, trong tương lai của BigQuery, v.v. Vì vậy, nếu bạn đang thực hiện phân tích, Parquet là một lựa chọn tốt làm định dạng lưu trữ tham chiếu cho truy vấn bởi nhiều hệ thống

Các điểm chuẩn bạn hiển thị sẽ rất ồn ào vì dữ liệu bạn đọc và ghi là rất nhỏ. Bạn nên thử nén ít nhất 100MB hoặc 1GB dữ liệu trở lên để nhận được một số điểm chuẩn thông tin hơn, xem ví dụ: http://wesmckinney.com/blog/python-parquet-multithreading/

Hi vọng điêu nay co ich


2
Vâng, "nén" sẽ luôn là một lựa chọn
Wes McKinney

1
Tôi nhận thấy rằng generate_floatschức năng của bạn trong mã điểm chuẩn của bạn tại đây wesmckinney.com/blog/python-parquet-update không đảm bảo unique_values. Chúng chỉ là ngẫu nhiên. Với n = 100M, tôi có hai trong số mười lần chạy. Chỉ đề cập trong trường hợp ai đó sử dụng chức năng này, nơi cần đảm bảo tính duy nhất.
Darkonaut

1
@Darkonaut chỉ tự hỏi ... kết quả nén ở kích thước nhỏ hơn để đọc nó vào bộ nhớ sẽ nhanh hơn. Có thể là quá trình xử lý thêm do nén / giải nén sẽ vẫn nhanh hơn so với việc phải đọc nhiều byte hơn. Hay bạn có một tình huống mà tôi không nghĩ đến?
PascalVKooten

1
HDF5 nói chung hơn và nặng hơn ... cũng chậm hơn rất nhiều trong hầu hết thời gian.
ivo Welch,

3
@WesMcKinney Tôi nhận thấy câu trả lời của bạn được viết vào năm 2018. Sau 2,3 ​​năm, bạn vẫn nghĩ Arrow (lông vũ) không tốt để lưu trữ lâu dài (bằng cách so sánh với Parquet)? Có lý do cụ thể không? Thích sự ổn định? sự tiến hóa định dạng? hoặc là?
HCSF
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.