创建 Arrow 对象

与创建数组、表格、张量和所有其他 Arrow 实体相关的食谱。

创建数组

Arrow 将数据保存在连续数组中,这些数组针对内存占用和 SIMD 分析进行了优化。在 Python 中,可以从 Python lists(或一般序列类型)、numpy 数组和 pandas 系列构建 pyarrow.Array

import pyarrow as pa

array = pa.array([1, 2, 3, 4, 5])
print(array)
[
  1,
  2,
  3,
  4,
  5
]

数组还可以提供一个 mask 来指定哪些值应被视为空值。

import numpy as np

array = pa.array([1, 2, 3, 4, 5],
                 mask=np.array([True, False, True, False, True]))

print(array)
[
  null,
  2,
  null,
  4,
  null
]

numpypandas 构建数组时,Arrow 将利用优化的代码路径,这些路径依赖于 numpypandas 对数据的内部内存表示。

import numpy as np
import pandas as pd

array_from_numpy = pa.array(np.arange(5))
array_from_pandas = pa.array(pd.Series([1, 2, 3, 4, 5]))

创建表格

Arrow 在 pyarrow.Table 中支持表格数据:每列都由一个 pyarrow.ChunkedArray 表示,并且可以通过将多个数组与它们的列名称配对来创建表格。

import pyarrow as pa

table = pa.table([
    pa.array([1, 2, 3, 4, 5]),
    pa.array(["a", "b", "c", "d", "e"]),
    pa.array([1.0, 2.0, 3.0, 4.0, 5.0])
], names=["col1", "col2", "col3"])

print(table)
pyarrow.Table
col1: int64
col2: string
col3: double
----
col1: [[1,2,3,4,5]]
col2: [["a","b","c","d","e"]]
col3: [[1,2,3,4,5]]

从普通类型创建表格

Arrow 允许从 numpy 和 pandas 数组和系列快速创建零拷贝的箭头数组,但也可以从普通 Python 结构创建 Arrow 数组和表格。

The pyarrow.table() 函数允许从各种输入创建表格,包括普通 Python 对象。

import pyarrow as pa

table = pa.table({
    "col1": [1, 2, 3, 4, 5],
    "col2": ["a", "b", "c", "d", "e"]
})

print(table)
pyarrow.Table
col1: int64
col2: string
----
col1: [[1,2,3,4,5]]
col2: [["a","b","c","d","e"]]

注意

字典中提供的所有值都将传递给 pyarrow.array() 以转换为 Arrow 数组,并且在可能的情况下将受益于零拷贝行为。

The pyarrow.Table.from_pylist() 方法允许从 python 行字典列表创建表格。如果未显式传递模式,则会推断类型。

import pyarrow as pa

table = pa.Table.from_pylist([
    {"col1": 1, "col2": "a"},
    {"col1": 2, "col2": "b"},
    {"col1": 3, "col2": "c"},
    {"col1": 4, "col2": "d"},
    {"col1": 5, "col2": "e"}
])

print(table)
pyarrow.Table
col1: int64
col2: string
----
col1: [[1,2,3,4,5]]
col2: [["a","b","c","d","e"]]

创建记录批次

Arrow 中的大多数 I/O 操作发生在将数据批次发送到其目的地时。 pyarrow.RecordBatch 是 Arrow 表示数据批次的方式。RecordBatch 可以看作是表格的一部分。

import pyarrow as pa

batch = pa.RecordBatch.from_arrays([
    pa.array([1, 3, 5, 7, 9]),
    pa.array([2, 4, 6, 8, 10])
], names=["odd", "even"])

可以使用 pyarrow.Table.from_batches() 将多个批次组合成一个表格。

second_batch = pa.RecordBatch.from_arrays([
    pa.array([11, 13, 15, 17, 19]),
    pa.array([12, 14, 16, 18, 20])
], names=["odd", "even"])

table = pa.Table.from_batches([batch, second_batch])
print(table)
pyarrow.Table
odd: int64
even: int64
----
odd: [[1,3,5,7,9],[11,13,15,17,19]]
even: [[2,4,6,8,10],[12,14,16,18,20]]

同样,pyarrow.Table 可以使用 pyarrow.Table.to_batches() 方法转换为 pyarrow.RecordBatch 列表。

record_batches = table.to_batches(max_chunksize=5)
print(len(record_batches))
2

存储分类数据

Arrow 提供了 pyarrow.DictionaryArray 类型来表示分类数据,而无需存储和重复类别。当列可能具有较大的值(例如文本)时,这可以减少内存使用。

如果您有一个包含重复分类数据的数组,可以使用 pyarrow.Array.dictionary_encode() 将其转换为 pyarrow.DictionaryArray

arr = pa.array(["red", "green", "blue", "blue", "green", "red"])

categorical = arr.dictionary_encode()
print(categorical)
...
-- dictionary:
  [
    "red",
    "green",
    "blue"
  ]
-- indices:
  [
    0,
    1,
    2,
    2,
    1,
    0
  ]

如果您已经知道类别和索引,那么您可以跳过编码步骤,并直接使用 pyarrow.DictionaryArray.from_arrays() 创建 DictionaryArray

categorical = pa.DictionaryArray.from_arrays(
    indices=[0, 1, 2, 2, 1, 0],
    dictionary=["red", "green", "blue"]
)
print(categorical)
...
-- dictionary:
  [
    "red",
    "green",
    "blue"
  ]
-- indices:
  [
    0,
    1,
    2,
    2,
    1,
    0
  ]