(十四)保存数组与按需读取
1. 文本表格与数组文件
第五章使用 CSV 保存业务记录。纯数值表格可以用 savetxt 写出、loadtxt 读回;书籍 CSV 里还有带引号的书名、JSON 标签和文本状态,继续先由 csv 模块解析,再选取适合计算的数值。
# 项目文件:demos/array_io.py
# CSV 便于查看,npy 保留 dtype 与 shape,npz 在一个归档中保存多份数组。
import tempfile
from pathlib import Path
import numpy as np
with tempfile.TemporaryDirectory() as folder:
root = Path(folder)
a = np.array([[10, 20], [30, 40]], dtype=np.int64)
np.savetxt(root / "minutes.csv", a, fmt="%d", delimiter=",")
print(
"文本往返",
np.loadtxt(root / "minutes.csv", delimiter=",", dtype=np.int64).tolist(),
)
np.save(root / "minutes.npy", a)
mapped = np.load(root / "minutes.npy", mmap_mode="r", allow_pickle=False)
print("映射", mapped.shape, mapped.dtype.name, mapped[1].tolist())
del mapped
np.savez_compressed(root / "sample.npz", minutes=a, valid=np.array([True, False]))
with np.load(root / "sample.npz", allow_pickle=False) as archive:
print("归档", archive.files, archive["valid"].tolist())savetxt(...,fmt="%d",delimiter=",") 用逗号分隔整数;loadtxt 指定同样的分隔符与数值类型。文本没有完整保存数组的类型信息,读取时需要重新指定。
np.save 的 .npy 文件保存 dtype、shape 和元素数据。np.savez_compressed 则用名称把多份数组放进一个压缩的 .npz 归档;with 结束后关闭归档资源。这里保存普通数值与 Unicode 文本数组,读取设置 allow_pickle=False。数组文件读取
2. 大文件先读需要的部分
读取 .npy 时的 mmap_mode="r" 建立只读内存映射,可以通过索引按需访问文件数据。它不要求先把整个文件复制进一份普通数组,但对全部数据做运算仍然需要读取相应内容,产生的结果也仍需存储。示例读出第二行 [30,40],之后释放映射再清理临时目录。
压缩归档需要解压相应成员,不能把它当作同样的直接映射文件。频繁分块访问的大数组,可以先保存为 .npy,按行切片处理。