Python中含浮点/数组属性的对象存储方案咨询(支持后续加载)
存储含NumPy数组的Python对象以复用的简单方案
现有简化示例代码:
class Atom: def __init__(self, name_ID, position, mass, charge): self.name_ID = name_ID # + date self.position, self.mass, self.charge = position, mass, charge def calculate_equation_of_motion(self): self.position, self.mass, self.charge = np.random.rand(3,3),np.random.rand(3,3),np.random.rand(3,3) def store_data(self): pass At30 = Atom('test', 0,0,0) At30.calculate_equation_of_motion() #At30.store_data() #At30_copy = load_object(name_ID='atom_30') #print(At30_copy.charge)实际场景中该类包含10个以上属性,涵盖浮点型参数与数组型变量,数组计算过程耗时较长,需要简单方案存储对象以便后续加载复用。
方案1:用pickle(Python标准库,零额外依赖)
pickle是Python自带的序列化工具,能直接处理包括NumPy数组在内的绝大多数Python对象,不用装额外包,适合快速实现。
修改代码实现存储与加载
import pickle import numpy as np class Atom: def __init__(self, name_ID, position, mass, charge): self.name_ID = name_ID # + date self.position, self.mass, self.charge = position, mass, charge def calculate_equation_of_motion(self): self.position, self.mass, self.charge = np.random.rand(3,3),np.random.rand(3,3),np.random.rand(3,3) def store_data(self, filepath=None): # 默认用name_ID做文件名,也可以自定义路径 if not filepath: filepath = f"{self.name_ID}.pkl" with open(filepath, 'wb') as f: pickle.dump(self, f) # 加载对象的工具函数 def load_object(filepath): with open(filepath, 'rb') as f: return pickle.load(f) # 实际使用流程 At30 = Atom('test', 0,0,0) At30.calculate_equation_of_motion() At30.store_data() # 自动存为test.pkl # 后续复用的时候直接加载 At30_copy = load_object('test.pkl') print(At30_copy.charge)
注意事项
- 加载对象时,
Atom类的结构要和存储时一致(比如不能随便删改属性),否则可能加载失败。 - 读写必须用二进制模式:写用
wb,读用rb。
方案2:用joblib(针对NumPy数组优化,速度更快)
如果你的对象里有大量大型NumPy数组,joblib比pickle效率更高,存储和加载速度更快,文件体积也可能更小。先装包:pip install joblib
代码实现
import joblib import numpy as np class Atom: def __init__(self, name_ID, position, mass, charge): self.name_ID = name_ID # + date self.position, self.mass, self.charge = position, mass, charge def calculate_equation_of_motion(self): self.position, self.mass, self.charge = np.random.rand(3,3),np.random.rand(3,3),np.random.rand(3,3) def store_data(self, filepath=None): if not filepath: filepath = f"{self.name_ID}.joblib" joblib.dump(self, filepath) # 加载函数 def load_object(filepath): return joblib.load(filepath) # 使用示例 At30 = Atom('test', 0,0,0) At30.calculate_equation_of_motion() At30.store_data() At30_copy = load_object('test.joblib') print(At30_copy.position)
核心优势
- 专门对NumPy数组做了序列化优化,处理大数组时比
pickle快很多。 - 支持分块存储,超大型数组也能轻松处理。
方案3:用HDF5(适合单独访问属性的场景)
如果后续需要单独读取对象里的某个属性(比如只加载charge而不是整个Atom对象),可以用h5py把每个属性单独存起来。装包:pip install h5py
代码示例
import h5py import numpy as np class Atom: def __init__(self, name_ID, position, mass, charge): self.name_ID = name_ID # + date self.position, self.mass, self.charge = position, mass, charge def calculate_equation_of_motion(self): self.position, self.mass, self.charge = np.random.rand(3,3),np.random.rand(3,3),np.random.rand(3,3) def store_data(self, filepath=None): if not filepath: filepath = f"{self.name_ID}.h5" with h5py.File(filepath, 'w') as f: # 存储字符串类型的属性 f.attrs['name_ID'] = self.name_ID # 存储数组类型的属性 f.create_dataset('position', data=self.position) f.create_dataset('mass', data=self.mass) f.create_dataset('charge', data=self.charge) # 加载函数,可选择加载整个对象或单独属性 def load_object(filepath): with h5py.File(filepath, 'r') as f: name_ID = f.attrs['name_ID'] position = f['position'][()] mass = f['mass'][()] charge = f['charge'][()] return Atom(name_ID, position, mass, charge) # 使用流程 At30 = Atom('test', 0,0,0) At30.calculate_equation_of_motion() At30.store_data() At30_copy = load_object('test.h5') print(At30_copy.mass)
额外好处
- 可以单独加载某个属性,不用把整个对象读进内存,节省资源。
- HDF5是通用格式,用MATLAB、R等其他语言也能读取。
内容的提问来源于stack exchange,提问作者nuwe
相关产品推荐
相关产品推荐

