羽毛和镶木地板有什么区别?
What are the differences between feather and parquet?
两者都是列式(磁盘)存储格式,用于数据分析系统。
两者都集成在 python 的 Apache Arrow (pyarrow 包中)并且是
旨在作为柱状内存分析层与 Arrow 相对应。
两种格式有何不同?
在可能的情况下使用 pandas 时,您是否应该始终更喜欢羽毛?
feather is more suitable than parquet 和
反过来?
附录
我在这里找到了一些提示 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
Parquet格式是为长期存储而设计的,而Arrow更适合短期或临时存储(1.0.0版本发布后Arrow可能更适合长期存储,因为二进制格式会很稳定)
Parquet 比 Feather 的编写成本更高,因为它具有更多的编码和压缩层。 Feather 是未修改的原始柱状 Arrow 内存。以后我们可能会在 Feather 中添加简单的压缩。
由于字典编码、RLE编码和数据页压缩,Parquet文件通常会比Feather文件小很多
Parquet 是一种标准的分析存储格式,受许多不同系统的支持:Spark、Hive、Impala、各种 AWS 服务,未来将由 BigQuery 等支持。因此,如果您做分析,Parquet 是一个很好的选择,作为多系统查询的参考存储格式
您显示的基准测试会非常嘈杂,因为您读取和写入的数据非常小。您应该尝试压缩至少 100MB 或以上 1GB 的数据以获得更多信息基准,请参见例如http://wesmckinney.com/blog/python-parquet-multithreading/
希望这对您有所帮助
我还会在 parquet 和 feather 之间的比较中包括不同的压缩方法,以检查 importing/exporting 速度和它使用多少存储空间。
我提倡为想要更好的 csv 替代方案的普通用户提供 2 个选项:
- 带有“gzip”压缩的 parquet(用于存储):导出比仅 .csv 快得多(如果 csv 需要压缩,则 parquet 快得多)。导入速度比 csv 快约 2 倍。压缩后的文件大小约为原始文件大小的 22%,与压缩的 csv 文件大致相同。
- 使用“zstd”压缩的羽毛(I/O 速度):与 csv 相比,羽毛导出的导出速度提高了 20 倍,导入速度提高了大约 6 倍。存储空间大约是原始文件大小的 32%,比 parquet“gzip”和压缩的 csv 差 10%,但仍然不错。
在所有类别中,两者都是比普通 csv 文件更好的选择(I/O 速度和存储)。
我分析了以下格式:
- csv
- csv 使用“zip”压缩
- 使用“zstd”压缩的羽化
- 羽化使用“lz4”压缩
- parquet 使用“snappy”压缩
- 使用“gzip”压缩的 parquet
- 镶木地板使用“gzip”brotli
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)
观察:
- Feather 似乎更适合轻量级数据,因为它写入和加载速度更快。 Parquet 具有更好的存储比率。
- Feather 库的支持和维护让我一开始很担心,但是文件格式与 pandas 集成良好,我可以使用
conda
为“zstd”压缩方法安装依赖项。
- 迄今为止最好的存储是使用“brotli”压缩的镶木地板,但是导出需要很长时间。导出完成后导入速度很快,但导入速度仍然比 feather 慢 2.5 倍。
两者都是列式(磁盘)存储格式,用于数据分析系统。 两者都集成在 python 的 Apache Arrow (pyarrow 包中)并且是 旨在作为柱状内存分析层与 Arrow 相对应。
两种格式有何不同?
在可能的情况下使用 pandas 时,您是否应该始终更喜欢羽毛?
feather is more suitable than parquet 和 反过来?
附录
我在这里找到了一些提示 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
Parquet格式是为长期存储而设计的,而Arrow更适合短期或临时存储(1.0.0版本发布后Arrow可能更适合长期存储,因为二进制格式会很稳定)
Parquet 比 Feather 的编写成本更高,因为它具有更多的编码和压缩层。 Feather 是未修改的原始柱状 Arrow 内存。以后我们可能会在 Feather 中添加简单的压缩。
由于字典编码、RLE编码和数据页压缩,Parquet文件通常会比Feather文件小很多
Parquet 是一种标准的分析存储格式,受许多不同系统的支持:Spark、Hive、Impala、各种 AWS 服务,未来将由 BigQuery 等支持。因此,如果您做分析,Parquet 是一个很好的选择,作为多系统查询的参考存储格式
您显示的基准测试会非常嘈杂,因为您读取和写入的数据非常小。您应该尝试压缩至少 100MB 或以上 1GB 的数据以获得更多信息基准,请参见例如http://wesmckinney.com/blog/python-parquet-multithreading/
希望这对您有所帮助
我还会在 parquet 和 feather 之间的比较中包括不同的压缩方法,以检查 importing/exporting 速度和它使用多少存储空间。
我提倡为想要更好的 csv 替代方案的普通用户提供 2 个选项:
- 带有“gzip”压缩的 parquet(用于存储):导出比仅 .csv 快得多(如果 csv 需要压缩,则 parquet 快得多)。导入速度比 csv 快约 2 倍。压缩后的文件大小约为原始文件大小的 22%,与压缩的 csv 文件大致相同。
- 使用“zstd”压缩的羽毛(I/O 速度):与 csv 相比,羽毛导出的导出速度提高了 20 倍,导入速度提高了大约 6 倍。存储空间大约是原始文件大小的 32%,比 parquet“gzip”和压缩的 csv 差 10%,但仍然不错。
在所有类别中,两者都是比普通 csv 文件更好的选择(I/O 速度和存储)。
我分析了以下格式:
- csv
- csv 使用“zip”压缩
- 使用“zstd”压缩的羽化
- 羽化使用“lz4”压缩
- parquet 使用“snappy”压缩
- 使用“gzip”压缩的 parquet
- 镶木地板使用“gzip”brotli
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)
观察:
- Feather 似乎更适合轻量级数据,因为它写入和加载速度更快。 Parquet 具有更好的存储比率。
- Feather 库的支持和维护让我一开始很担心,但是文件格式与 pandas 集成良好,我可以使用
conda
为“zstd”压缩方法安装依赖项。 - 迄今为止最好的存储是使用“brotli”压缩的镶木地板,但是导出需要很长时间。导出完成后导入速度很快,但导入速度仍然比 feather 慢 2.5 倍。