入门#

Arrow 管理数组中的数据 (pyarrow.Array),这些数组可以分组到表 (pyarrow.Table) 中,以表示表格数据中的数据列。

Arrow 还为各种格式提供支持,以将这些表格数据导入和导出到磁盘和网络。最常用的格式是 Parquet (读取和写入 Apache Parquet 格式) 和 IPC 格式 (流式传输、序列化和 IPC)。

创建数组和表#

Arrow 中的数组是相同类型的数据集合。这允许 Arrow 使用性能最佳的实现来存储数据并对其执行计算。因此,每个数组都应该有数据和一个类型

In [1]: import pyarrow as pa

In [2]: days = pa.array([1, 12, 17, 23, 28], type=pa.int8())

多个数组可以组合成表,当附加到列名时,形成表格数据中的列

In [3]: months = pa.array([1, 3, 5, 7, 1], type=pa.int8())

In [4]: years = pa.array([1990, 2000, 1995, 2000, 1995], type=pa.int16())

In [5]: birthdays_table = pa.table([days, months, years],
   ...:                            names=["days", "months", "years"])
   ...: 

In [6]: birthdays_table
Out[6]: 
pyarrow.Table
days: int8
months: int8
years: int16
----
days: [[1,12,17,23,28]]
months: [[1,3,5,7,1]]
years: [[1990,2000,1995,2000,1995]]

有关更多详细信息,请参见 数据类型和内存数据模型

保存和加载表#

一旦你拥有表格数据,Arrow 提供了现成的功能来保存和恢复常用格式的数据,例如 Parquet

In [7]: import pyarrow.parquet as pq

In [8]: pq.write_table(birthdays_table, 'birthdays.parquet')

一旦你的数据在磁盘上,加载它回来只需一个函数调用,并且 Arrow 经过了大量的内存和速度优化,因此加载数据将尽可能快

In [9]: reloaded_birthdays = pq.read_table('birthdays.parquet')

In [10]: reloaded_birthdays
Out[10]: 
pyarrow.Table
days: int8
months: int8
years: int16
----
days: [[1,12,17,23,28]]
months: [[1,3,5,7,1]]
years: [[1990,2000,1995,2000,1995]]

在 arrow 中保存和加载数据通常通过 Parquet, IPC 格式 (Feather 文件格式), CSV行分隔的 JSON 格式完成。

执行计算#

Arrow 附带了一堆可以应用于其数组和表的计算函数,因此通过计算函数可以对数据应用转换

In [11]: import pyarrow.compute as pc

In [12]: pc.value_counts(birthdays_table["years"])
Out[12]: 
<pyarrow.lib.StructArray object at 0x7f9d841b52a0>
-- is_valid: all not null
-- child 0 type: int16
  [
    1990,
    2000,
    1995
  ]
-- child 1 type: int64
  [
    1,
    2,
    2
  ]

有关可用计算函数列表以及如何使用它们,请参见 计算函数

处理大型数据#

Arrow 还提供了 pyarrow.dataset API 来处理大型数据,它将为你处理将数据分区为更小的块

In [13]: import pyarrow.dataset as ds

In [14]: ds.write_dataset(birthdays_table, "savedir", format="parquet",
   ....:                  partitioning=ds.partitioning(
   ....:                     pa.schema([birthdays_table.schema.field("years")])
   ....:                 ))
   ....: 

重新加载分区数据集将检测到这些块

In [15]: birthdays_dataset = ds.dataset("savedir", format="parquet", partitioning=["years"])

In [16]: birthdays_dataset.files
Out[16]: 
['savedir/1990/part-0.parquet',
 'savedir/1995/part-0.parquet',
 'savedir/2000/part-0.parquet']

并且仅在迭代它们时才会延迟加载数据块

In [17]: import datetime

In [18]: current_year = datetime.datetime.utcnow().year

In [19]: for table_chunk in birthdays_dataset.to_batches():
   ....:     print("AGES", pc.subtract(current_year, table_chunk["years"]))
   ....: 
AGES [
  35
]
AGES [
  30,
  30
]
AGES [
  25,
  25
]

有关如何处理大数据集、如何过滤它们、如何投影它们等的更多详细信息,请参阅 表格数据集 文档。

从这里继续#

要深入了解 Arrow,您可能需要阅读 PyArrow 文档 本身或 Arrow Python Cookbook