깃털과 쪽모이 세공의 차이점은 무엇입니까?


89

둘 다 데이터 분석 시스템에서 사용하기위한 컬럼 형 (디스크) 스토리지 형식 입니다. 둘 다 Apache Arrow ( python 용 pyarrow 패키지)에 통합되어 있으며 Arrow 와 함께 컬럼 형 인 메모리 분석 계층 으로 대응하도록 설계되었습니다 .

두 형식은 어떻게 다릅니 까?

가능하면 팬더로 작업 할 때 항상 깃털을 선호해야합니까?

깃털쪽모이 세공 보다 더 적합한 사용 사례는 무엇입니까 ?


부록

여기 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

답변:


130
  • Parquet 형식은 장기 저장을 위해 설계되었으며 Arrow는 단기 또는 임시 저장에 더 적합합니다 (Arrow는 1.0.0 릴리스 이후 장기 저장에 더 적합 할 수 있습니다. 바이너리 형식이 안정되기 때문입니다)

  • Parquet은 더 많은 인코딩 및 압축 계층을 제공하므로 Feather보다 쓰기 비용이 더 많이 듭니다. 페더는 수정되지 않은 원시 원주 형 화살표 메모리입니다. 앞으로 Feather에 간단한 압축을 추가 할 것입니다.

  • 사전 인코딩, RLE 인코딩 및 데이터 페이지 압축으로 인해 Parquet 파일은 종종 Feather 파일보다 훨씬 작습니다.

  • Parquet은 Spark, Hive, Impala, 다양한 AWS 서비스, 향후 BigQuery 등 다양한 시스템에서 지원되는 분석을위한 표준 스토리지 형식입니다. 따라서 분석을 수행하는 경우 Parquet은 다음을위한 참조 스토리지 형식으로 좋은 옵션입니다. 여러 시스템에서 쿼리

당신이 보여준 벤치 마크는 당신이 읽고 쓴 데이터가 매우 작기 때문에 매우 시끄러울 것입니다. 좀 더 유익한 벤치 마크를 얻으려면 최소 100MB 또는 1GB 이상의 데이터를 압축해야합니다 (예 : http://wesmckinney.com/blog/python-parquet-multithreading/ 참조) .

도움이 되었기를 바랍니다


2
예, "비 압축"은 항상 옵션입니다
Wes McKinney

1
generate_floats벤치 마크 코드 의 기능이 wesmckinney.com/blog/python-parquet-update를 보장하지 않는 것으로 나타났습니다 unique_values. 그들은 단지 무작위입니다. n = 100M으로 10 번 중 2 번 중복을 얻었습니다. 누군가가 고유성이 보장되어야하는이 함수를 사용하는 경우를 언급합니다.
Darkonaut

1
@Darkonaut가 궁금해합니다. 압축은 크기가 작아 지므로 메모리로 읽는 것이 더 빠를 것입니다. 압축 / 압축 해제로 인한 추가 처리가 더 많은 바이트를 읽는 것보다 더 빠를 수 있습니다. 아니면 내가 생각하지 않는 상황이 있습니까?
PascalVKooten

1
HDF5는 더 일반적이고 무겁습니다 ... 또한 대부분의 경우 훨씬 느립니다.
ivo Welch

3
@WesMcKinney 귀하의 답변이 2018 년에 작성되었음을 확인했습니다. 2.3 년 후에도 Arrow (깃털)가 장기 보관에 적합하지 않다고 생각하십니까 (Parquet과 비교하여)? 특별한 이유가 있습니까? 안정성처럼? 포맷 진화? 또는?
HCSF
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.