PyArrow — Apache Arrow 的 Python 绑定,高速列式内存数据处理
一句话说明
PyArrow 是 Apache Arrow 的 Python 接口,用列式内存格式存数据,让 pandas/NumPy/Spark 之间零拷贝传输,处理大数据快 5-10 倍。
安装与配置
# pip 安装(推荐)
pip install pyarrow # 当前最新 24.0.0(2026-04)
# conda 安装
conda install -c conda-forge pyarrow
# 验证版本
python -c "import pyarrow as pa; print(pa.__version__)"
核心用法
基本数据类型
import pyarrow as pa # 导入 PyArrow
# 创建 Array(列式数组)
arr = pa.array([1, 2, 3, None, 5]) # None 自动变 null
print(arr.type) # int64
print(arr.null_count) # 输出:1,表示有一个空值
# 创建有类型的 Array
float_arr = pa.array([1.1, 2.2], type=pa.float32()) # 指定 float32
str_arr = pa.array(["hello", "world"]) # 字符串数组
创建表格(Table)
# 用字典创建 Table(相当于 pandas DataFrame)
table = pa.table({
"id": [1, 2, 3], # 第一列
"name": ["Alice", "Bob", "Carol"], # 第二列
"score":[95.5, 87.0, 92.3], # 第三列
})
print(table.schema) # 打印列名和数据类型
print(table.num_rows) # 行数:3
print(table.column("name")) # 取出 name 列
与 pandas 互转
import pandas as pd
# pandas → Arrow(内存零拷贝)
df = pd.DataFrame({"a": [1, 2, 3], "b": ["x", "y", "z"]})
table = pa.Table.from_pandas(df) # 转为 Arrow Table
# Arrow → pandas
df2 = table.to_pandas() # 转回 pandas DataFrame
实战案例
读写 Parquet 文件
import pyarrow.parquet as pq # Parquet 子模块
# 写 Parquet
pq.write_table(table, "output.parquet") # 保存为 Parquet 格式
# 读 Parquet(懒加载,只读需要的列)
loaded = pq.read_table(
"output.parquet",
columns=["id", "score"], # 只读这两列,省内存
)
print(loaded.to_pandas())
# 分片写大文件(适合超过内存的数据)
writer = pq.ParquetWriter("big.parquet", table.schema)
for chunk in big_data_generator(): # 迭代数据块
writer.write_table(pa.Table.from_pandas(chunk))
writer.close() # 必须关闭
过滤与计算
import pyarrow.compute as pc # 计算子模块
# 列运算
scores = pa.array([95.5, 87.0, 92.3, 78.0])
mask = pc.greater(scores, 90.0) # 找出 >90 的
result = pc.filter(scores, mask) # 过滤
print(result) # [95.5, 92.3]
# 字符串处理
names = pa.array(["Alice", "bob", "CAROL"])
lower = pc.ascii_lower(names) # 转小写
常见报错与解决
| 报错 | 原因 | 解决 |
|---|
ArrowInvalid: Could not convert | 混合类型无法推断 | 用 type= 显式指定类型 |
ArrowMemoryError | 数据超内存 | 改用分批读写或 ParquetWriter |
pyarrow.lib.ArrowNotImplementedError | 不支持该操作 | 先转 pandas 再操作 |
ValueError: Mixing scalar and array | 标量/数组混用 | 统一为列表或 pa.scalar() |
速查表
| 操作 | 代码 |
|---|
| 创建数组 | pa.array([1,2,3]) |
| 创建表格 | pa.table({"col": [...]}) |
| pandas 转 Arrow | pa.Table.from_pandas(df) |
| Arrow 转 pandas | table.to_pandas() |
| 写 Parquet | pq.write_table(table, "f.parquet") |
| 读 Parquet | pq.read_table("f.parquet") |
| 列计算 | pc.greater(arr, 90) |
| 过滤 | pc.filter(arr, mask) |