人工智能之數據分析 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 pickle
with open('data.pkl', 'wb') as f:
pickle.dump(arr, f)
with open('data.pkl', 'rb') as f:
loaded = pickle.load(f)
⚠️ 缺點:
- 不跨語言
- 安全風險(反序列化gongji)
- 比
.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 pd
df = 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》