Apache Parquet 格式的读取与写入

Apache Parquet 格式的读取与写入#

Apache Parquet 项目提供了标准化的开源列式存储格式,用于数据分析系统。它最初是为 Apache Hadoop 创建的,后来被 Apache DrillApache HiveApache ImpalaApache Spark 等系统采用,作为高性能数据 IO 的共同标准。

Apache Arrow 是用于读取或写入 Parquet 文件的数据的理想内存传输层。一直在并行开发 Apache Parquet 的 C++ 实现,其中包括原生的、多线程的 C++ 适配器,用于与内存中的 Arrow 数据进行交互。PyArrow 包含了这段代码的 Python 绑定,因此也能使用 pandas 来读取和写入 Parquet 文件。

获取支持 Parquet 的 pyarrow#

如果你使用 pipconda 安装了 pyarrow,它应该已经内置了对 Parquet 的支持:

import pyarrow.parquet as pq

读取和写入单个文件#

函数 read_table()write_table() 分别用于读取和写入 pyarrow.Table对象。

让我们来看一个简单的表格:

import numpy as np

import pandas as pd

import pyarrow as pa

df = pd.DataFrame({'one': [-1, np.nan, 2.5],
                   'two': ['foo', 'bar', 'baz'],
                   'three': [True, False, True]},
                   index=list('abc'))

table = pa.Table.from_pandas(df)

将此使用 write_table 函数写入 Parquet 格式:

import pyarrow.parquet as pq

pq.write_table(table, 'example.parquet')

这将创建一个单一的 Parquet 文件。实际上,一个 Parquet 数据集可能包含许多目录中的多个文件。我们可以使用 read_table 函数将单个文件读取回来:

table2 = pq.read_table('example.parquet')

table2.to_pandas()
one two three
a -1.0 foo True
b NaN bar False
c 2.5 baz True

你可以传递一部分列来进行读取,这比读取整个文件要快得多(由于列式布局):

pq.read_table('example.parquet', columns=['one', 'three']).to_pandas()
one three
0 -1.0 True
1 NaN False
2 2.5 True

当从使用 Pandas dataframe 作为源的文件中读取部分列时,我们使用 read_pandas 来保持任何额外的索引列数据:

pq.read_pandas('example.parquet', columns=['two']).to_pandas()
two
a foo
b bar
c baz

不需要使用字符串来指定文件的来源。它可以是以下任何一种:

  • 字符串形式的文件路径

  • 来自 PyArrow 的 NativeFile

  • Python 文件对象

一般来说,Python 文件对象的读取性能最差,而字符串文件路径或 NativeFile 实例(尤其是内存映射)的性能最好。