读取和写入 Apache ORC 格式#
该 Apache ORC 项目提供了一种标准化的开源列式存储格式,供数据分析系统使用。它最初是为了在 Apache Hadoop 中使用而创建的,像 Apache Drill、Apache Hive、Apache Impala 和 Apache Spark 等系统都采用了它作为高性能数据 I/O 的共享标准。
Apache Arrow 是用于使用 ORC 文件读取或写入的数据的理想内存表示层。
获取支持 ORC 的 pyarrow#
如果您使用 pip 或 conda 安装了 pyarrow
,则它应该内置了 ORC 支持。
>>> from pyarrow import orc
如果您从源代码构建 pyarrow
,则在编译 C++ 库时必须使用 -DARROW_ORC=ON
,并在构建 pyarrow
时启用 ORC 扩展。有关更多详细信息,请参见 Python 开发 页面。
读取和写入单个文件#
函数 read_table()
和 write_table()
分别读取和写入 pyarrow.Table 对象。
让我们看看一个简单的表格
>>> import numpy as np
>>> import pyarrow as pa
>>> table = pa.table(
... {
... 'one': [-1, np.nan, 2.5],
... 'two': ['foo', 'bar', 'baz'],
... 'three': [True, False, True]
... }
... )
我们使用 write_table
将其写入 ORC 格式
>>> from pyarrow import orc
>>> orc.write_table(table, 'example.orc')
这将创建一个单个 ORC 文件。在实践中,ORC 数据集可能包含许多目录中的许多文件。我们可以使用 read_table
读取单个文件
>>> table2 = orc.read_table('example.orc')
您可以传递一个列的子集进行读取,这比读取整个文件快得多(由于列式布局)。
>>> orc.read_table('example.orc', columns=['one', 'three'])
pyarrow.Table
one: double
three: bool
----
one: [[-1,nan,2.5]]
three: [[true,false,true]]
我们无需使用字符串来指定文件的来源。它可以是以下任何一种:
一个文件路径字符串
一个 Python 文件对象
一个 pathlib.Path 对象
一个来自 PyArrow 的 NativeFile
通常,Python 文件对象将具有最差的读取性能,而字符串文件路径或 NativeFile
的实例(尤其是内存映射)将具有最佳的性能。
我们还可以通过 pyarrow.dataset
接口读取具有多个 ORC 文件的分区数据集。
另请参阅
ORC 文件写入选项#
write_table()
有许多选项可以控制写入 ORC 文件时的各种设置。
file_version
,要使用的 ORC 格式版本。'0.11'
确保与旧版读取器兼容,而'0.12'
是较新的版本。stripe_size
,用于控制列条带内数据的近似大小。 目前默认为 64MB。
有关更多详细信息,请参阅 write_table()
文档字符串。
更细粒度的读取和写入#
read_table
使用 ORCFile
类,该类具有其他功能
>>> orc_file = orc.ORCFile('example.orc')
>>> orc_file.metadata
-- metadata --
>>> orc_file.schema
one: double
two: string
three: bool
>>> orc_file.nrows
3
有关更多详细信息,请参阅 ORCFile
文档字符串。
正如您可以在 Apache ORC 格式 中了解更多信息一样,ORC 文件由多个条带组成。 read_table
将读取所有条带并将它们连接成一个表。 您可以使用 read_stripe
读取各个条带。
>>> orc_file.nstripes
1
>>> orc_file.read_stripe(0)
pyarrow.RecordBatch
one: double
two: string
three: bool
我们可以使用 ORCWriter
写入 ORC 文件。
>>> with orc.ORCWriter('example2.orc') as writer:
... writer.write(table)
压缩#
行组中列内的數據頁可以在編碼步驟(字典、RLE 編碼)之後進行壓縮。 在 PyArrow 中,我們默認不使用壓縮,但還支持 Snappy、ZSTD、Gzip/Zlib 和 LZ4。
>>> orc.write_table(table, where, compression='uncompressed')
>>> orc.write_table(table, where, compression='gzip')
>>> orc.write_table(table, where, compression='zstd')
>>> orc.write_table(table, where, compression='snappy')
Snappy 通常會帶來更好的性能,而 Gzip 可能會產生更小的文件。
從雲存儲中讀取#
除了本地文件之外,pyarrow 還通過 filesystem
關鍵字支持其他文件系統,例如雲文件系統。
>>> from pyarrow import fs
>>> s3 = fs.S3FileSystem(region="us-east-2")
>>> table = orc.read_table("bucket/object/key/prefix", filesystem=s3)
另请参阅