programing

깃털과 파켓의 차이점은 무엇입니까?

oldcodes 2023. 7. 3. 23:09
반응형

깃털과 파켓의 차이점은 무엇입니까?

둘 다 데이터 분석 시스템에 사용하기 위한 기둥형(디스크) 스토리지 형식입니다.둘 다 Apache Arrow(파이썬용 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
  • Parquet 형식은 장기 저장용으로 설계되었으며, Arrow는 단기 또는 일시적 저장용으로 더 적합합니다(1.0.0 릴리스 이후에는 바이너리 형식이 안정적이기 때문에 장기 저장용으로 더 적합할 수 있습니다).

  • Parquet은 인코딩 및 압축 계층이 더 많기 때문에 Feather보다 쓰기가 더 비쌉니다.깃털은 수정되지 않은 원시 열주형 화살표 메모리입니다.우리는 아마도 미래에 페더에 단순 압축을 추가할 것입니다.

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

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

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

또한 parquet과 feel의 서로 다른 압축 방법을 비교하여 가져오기/내보내기 속도와 스토리지 사용량을 확인할 수 있습니다.

저는 더 나은 CSV 대안을 원하는 일반 사용자를 위한 두 가지 옵션을 지지합니다.

  • "gzip" 압축을 사용한 파켓(저장용):단순히 .csv보다 내보내기가 훨씬 빠릅니다(csv를 압축해야 하는 경우 파켓이 훨씬 빠름).가져오기 속도는 csv보다 약 2배 빠릅니다.압축은 원래 파일 크기에서 약 22%로 압축된 CSV 파일과 거의 같습니다.
  • "zstd" 압축 기능을 갖춘 페더(I/O 속도용): csv에 비해 페더 내보내기가 20배, 가져오기가 약 6배 더 빠릅니다.스토리지는 원래 파일 크기보다 약 32% 향상되었으며, 이는 parquet "gzip" 및 csv zip보다 10% 더 나쁘지만 여전히 괜찮은 수준입니다.

둘 다 모든 범주(I/O 속도 및 스토리지)의 일반 CSV 파일보다 더 나은 옵션입니다.

다음 형식을 분석했습니다.

  1. csv
  2. csv "zip" 압축 사용
  3. "zstd" 압축을 사용한 깃털
  4. "lz4" 압축을 사용한 깃털
  5. "cruppy" 압축을 사용한 파켓
  6. "gzip" 압축을 사용한 파켓
  7. "브로틀리" 압축을 사용한 파켓

import zipfile
import pandas as pd
folder_path = (r"...\\intraday")
zip_path = zipfile.ZipFile(folder_path + "\\AAPL.zip")    
test_data = pd.read_csv(zip_path.open('AAPL.csv'))


# EXPORT, STORAGE AND IMPORT TESTS
# ------------------------------------------
# - FORMAT .csv 

# export
%%timeit
test_data.to_csv(folder_path + "\\AAPL.csv", index=False)
# 12.8 s ± 399 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# storage
# AAPL.csv exported using python.
# 169.034 KB

# import
%%timeit
test_data = pd.read_csv(folder_path + "\\AAPL.csv")
# 1.56 s ± 14.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# ------------------------------------------
# - FORMAT zipped .csv 

# export
%%timeit
test_data.to_csv(folder_path + "\\AAPL.csv")
# 12.8 s ± 399 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# OBSERVATION: this does not include the time I spent manually zipping the .csv

# storage
# AAPL.csv zipped with .zip "normal" compression using 7-zip software.
# 36.782 KB

# import
zip_path = zipfile.ZipFile(folder_path + "\AAPL.zip")
%%timeit
test_data = pd.read_csv(zip_path.open('AAPL.csv'))
# 2.31 s ± 43.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# ------------------------------------------
# - FORMAT .feather using "zstd" compression.

# export
%%timeit
test_data.to_feather(folder_path + "\\AAPL.feather", compression='zstd')
# 460 ms ± 13.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# storage
# AAPL.feather exported with python using zstd
# 54.924 KB

# import
%%timeit
test_data = pd.read_feather(folder_path + "\\AAPL.feather")
# 310 ms ± 11.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# ------------------------------------------
# - FORMAT .feather using "lz4" compression.
# Only works installing with pip, not with conda. Bad sign.

# export
%%timeit
test_data.to_feather(folder_path + "\\AAPL.feather", compression='lz4')
# 392 ms ± 14.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# storage
# AAPL.feather exported with python using "lz4"
# 79.668 KB    

# import
%%timeit
test_data = pd.read_feather(folder_path + "\\AAPL.feather")
# 255 ms ± 4.79 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# ------------------------------------------
# - FORMAT .parquet using compression "snappy"

# export
%%timeit
test_data.to_parquet(folder_path + "\\AAPL.parquet", compression='snappy')
# 2.82 s ± 47.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# storage
# AAPL.parquet exported with python using "snappy"
# 62.383 KB

# import
%%timeit
test_data = pd.read_parquet(folder_path + "\\AAPL.parquet")
# 701 ms ± 19.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# ------------------------------------------
# - FORMAT .parquet using compression "gzip"

# export
%%timeit
test_data.to_parquet(folder_path + "\\AAPL.parquet", compression='gzip')
# 10.8 s ± 77.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# storage
# AAPL.parquet exported with python using "gzip"
# 37.595 KB

# import
%%timeit
test_data = pd.read_parquet(folder_path + "\\AAPL.parquet")
# 1.18 s ± 80.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# ------------------------------------------
# - FORMAT .parquet using compression "brotli"

# export
%%timeit
test_data.to_parquet(folder_path + "\\AAPL.parquet", compression='brotli')
# around 5min each loop. I did not run %%timeit on this one.

# storage
# AAPL.parquet exported with python using "brotli"
# 29.425 KB    

# import
%%timeit
test_data = pd.read_parquet(folder_path + "\\AAPL.parquet")
# 1.04 s ± 72 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

관측치:

  • 깃털은 쓰기와 로딩 속도가 빠르기 때문에 경량 데이터에 더 적합한 것으로 보입니다.파켓은 저장 비율이 더 좋습니다.
  • 및 했지만, 잘 설치할 수 .conda" 방법의 .zstd 축법경 우의방.
  • 가장 좋은 스토리지는 "brotli" 압축 기능이 있는 parquet이지만 내보내기까지 시간이 오래 걸립니다.일단 수출이 완료되면 수입 속도는 좋지만 깃털보다 수입이 2.5배 느립니다.

언급URL : https://stackoverflow.com/questions/48083405/what-are-the-differences-between-feather-and-parquet

반응형