人工智能之数据分析 numpy
第十二章 数据持久化
前言
NumPy 提供了多种数据持久化(Persistence) 方式,用于高效地保存和加载数组数据。根据数据规模、结构复杂度、跨平台需求等不同场景,可选择不同的方法。
本文系统讲解:
- 基础二进制/文本保存(
.npy,.npz,.txt) - 结构化数组(Structured Arrays) 与 记录数组(Record Arrays)
- 内存映射(Memory Mapping) —— 处理超大文件
- 其他读写方式(如 HDF5、Pickle 等)
一、基础数据持久化
1. np.save() / np.load() —— 单个数组(推荐)
保存为 .npy 格式(NumPy 专用二进制格式),保留 dtype、形状、字节序。
import numpy as np# 保存
arr = np.array([1, 2, 3, 4])
np.save('data.npy', arr)# 加载
loaded = np.load('data.npy')
print(loaded) # [1 2 3 4]
✅ 优点:
- 高效(C 语言级 I/O)
- 支持任意维度和 dtype
- 元数据完整保留
2. np.savez() / np.savez_compressed() —— 多个数组
保存多个数组到一个 .npz 文件(ZIP 格式)。
a = np.array([1, 2, 3])
b = np.array([[4, 5], [6, 7]])# 无压缩
np.savez('arrays.npz', a=a, b=b)# 有压缩(节省空间)
np.savez_compressed('arrays_compressed.npz', a=a, b=b)# 加载
data = np.load('arrays.npz')
print(data['a']) # [1 2 3]
print(data['b']) # [[4 5] [6 7]]
data.close() # 显式关闭(或用 with)
💡
.npz文件本质是 ZIP,可用解压软件打开查看内容。
3. 文本格式:np.savetxt() / np.loadtxt()
适用于小规模、人类可读的数据(如 CSV 风格)。
arr = np.array([[1.1, 2.2], [3.3, 4.4]])# 保存为文本
np.savetxt('data.txt', arr, delimiter=',', fmt='%.2f')# 加载
loaded = np.loadtxt('data.txt', delimiter=',')
⚠️ 缺点:
- 只支持 1D/2D 数组
- 浮点精度可能丢失
- 速度慢、文件大
二、结构化数组(Structured Arrays)
当数据包含异构字段(如姓名、年龄、成绩),可使用结构化数组。
1. 定义 dtype
# 定义结构化 dtype
dt = np.dtype([('name', 'U10'), # Unicode 字符串,最长10字符('age', 'i4'), # 32位整数('score', 'f4') # 32位浮点
])# 创建数组
students = np.array([('Alice', 20, 85.5),('Bob', 22, 90.0)
], dtype=dt)print(students['name']) # ['Alice' 'Bob']
print(students[0]) # ('Alice', 20, 85.5)
2. 持久化结构化数组
# 保存
np.save('students.npy', students)# 加载
loaded_students = np.load('students.npy')
print(loaded_students.dtype) # 与原 dtype 一致
✅ 结构化数组可直接用 .npy 保存,完全保留字段信息。
三、记录数组(Record Arrays)—— 结构化数组的子类
提供属性访问语法(arr.name 而非 arr['name'])。
# 从结构化数组创建
rec_arr = np.rec.array(students)# 或直接创建
rec_arr2 = np.rec.array([('Charlie', 21, 88.0),('Diana', 19, 92.5)
], dtype=dt)print(rec_arr.name) # ['Alice' 'Bob'] ← 属性访问!
print(rec_arr.age) # [20 22]
⚠️ 注意:
np.rec.array是np.ndarray的子类,不推荐在新代码中使用(官方文档建议优先用结构化数组 + 字典式访问)。
但记录数组同样支持 np.save() / np.load()。
四、内存映射(Memory Mapping)—— 处理超大数组
当数组大于内存(如几十 GB 的科学数据),可使用 np.memmap 实现按需加载。
原理:
- 文件存储在磁盘
- NumPy 通过虚拟内存机制“映射”到数组
- 访问时自动从磁盘读取对应块,无需一次性加载
示例:
# 创建一个 10GB 的 float32 数组(仅占磁盘,不占内存)
filename = 'big_array.dat'
shape = (1000000, 2500) # ~10^10 元素 × 4 bytes ≈ 37.25 GB# 创建 memmap(mode='w+' 表示可读写)
big_arr = np.memmap(filename, dtype='float32', mode='w+', shape=shape)# 初始化(可选)
big_arr[:] = 0.0 # 实际只写入磁盘,内存占用极小# 使用(像普通数组一样)
big_arr[0, :10] = np.arange(10)# 刷新到磁盘(重要!)
big_arr.flush()# 之后可重新加载
loaded = np.memmap(filename, dtype='float32', mode='r', shape=shape)
print(loaded[0, :10]) # [0. 1. 2. ... 9.]
模式说明:
| mode | 说明 |
|---|---|
'r' |
只读 |
'r+' |
读写(文件必须存在) |
'w+' |
读写(覆盖或新建) |
'c' |
复制写(修改不影响原文件) |
✅ 适用场景:
- 卫星遥感图像
- 基因组数据
- 物理模拟快照
- 大型嵌入向量矩阵
五、其他常用读写方式
1. Pickle(Python 通用序列化)
import picklewith open('data.pkl', 'wb') as f:pickle.dump(arr, f)with open('data.pkl', 'rb') as f:loaded = pickle.load(f)
⚠️ 缺点:
- 不跨语言
- 安全风险(反序列化攻击)
- 比
.npy慢且文件更大
✅ 仅建议用于保存包含 NumPy 数组的复杂 Python 对象(如 dict、class 实例)。
2. HDF5(推荐用于大型科学数据)
通过 h5py 库支持:
import h5py# 写入
with h5py.File('data.h5', 'w') as f:f.create_dataset('my_array', data=arr)f.create_dataset('students', data=students) # 也支持结构化数组# 读取
with h5py.File('data.h5', 'r') as f:arr_h5 = f['my_array'][:] # 加载全部partial = f['my_array'][0:10] # 只加载前10行(支持切片!)
✅ HDF5 优势:
- 支持超大文件(TB 级)
- 分层数据组织(类似文件夹)
- 压缩(gzip, lzf)
- 跨平台、跨语言(C/Fortran/Python/Matlab)
- 支持部分读取(类似 memmap)
🔧 安装:
pip install h5py
3. Parquet / Feather(表格数据,配合 Pandas)
若数据是表格形式(类似 DataFrame),可先转为 Pandas 再保存:
import pandas as pddf = pd.DataFrame(students) # 结构化数组 → DataFrame
df.to_parquet('data.parquet') # 列式存储,高效压缩
df_loaded = pd.read_parquet('data.parquet')
六、选择建议:按场景选格式
| 场景 | 推荐格式 | 理由 |
|---|---|---|
| 单个数组,快速保存/加载 | .npy |
最快、最简单 |
| 多个数组 | .npz |
一个文件打包 |
| 人类可读、小数据 | .txt/.csv |
兼容 Excel |
| 异构字段(姓名/年龄等) | 结构化数组 +.npy |
保留字段语义 |
| 超大数组(> 内存) | np.memmap 或 HDF5 |
按需加载 |
| 科学数据共享 | HDF5 |
跨平台、压缩、元数据 |
| 与 Pandas 交互 | Parquet / HDF5 | 生态兼容 |
七、注意事项
- 路径与编码:
- 在 Windows 上注意路径分隔符(推荐用
pathlib) - 文本文件注意
encoding='utf-8'
- 在 Windows 上注意路径分隔符(推荐用
- 版本兼容性:
.npy格式随 NumPy 版本演进,但向后兼容良好
- 内存映射生命周期:
memmap对象应保持引用,避免过早释放- 修改后务必调用
.flush()
- 结构化数组字符串长度:
'U10'表示最多 10 个 Unicode 字符,不足会截断!
掌握这些持久化技术,我们可以灵活应对从 KB 到 TB 级别的数据存储需求。NumPy 的设计哲学是:小数据用 .npy,大数据用 memmap 或 HDF5,结构化数据用自定义 dtype。
后续
本文主要讲述了numpy数据持久化。python过渡项目部分代码已经上传至gitee,后续会逐步更新,主要受时间原因限制,当然自己也可以克隆到本地学习拓展。
资料关注
公众号:咚咚王
gitee:https://gitee.com/wy18585051844/ai_learning

《Python编程:从入门到实践》
《利用Python进行数据分析》
《算法导论中文第三版》
《概率论与数理统计(第四版) (盛骤) 》
《程序员的数学》
《线性代数应该这样学第3版》
《微积分和数学分析引论》
《(西瓜书)周志华-机器学习》
《TensorFlow机器学习实战指南》
《Sklearn与TensorFlow机器学习实用指南》
《模式识别(第四版)》
《深度学习 deep learning》伊恩·古德费洛著 花书
《Python深度学习第二版(中文版)【纯文本】 (登封大数据 (Francois Choliet)) (Z-Library)》
《深入浅出神经网络与深度学习+(迈克尔·尼尔森(Michael+Nielsen)》
《自然语言处理综论 第2版》
《Natural-Language-Processing-with-PyTorch》
《计算机视觉-算法与应用(中文版)》
《Learning OpenCV 4》
《AIGC:智能创作时代》杜雨+&+张孜铭
《AIGC原理与实践:零基础学大语言模型、扩散模型和多模态模型》
《从零构建大语言模型(中文版)》
《实战AI大模型》
《AI 3.0》