为什么在python中保存/加载数据需要比matlab更多的空间/时间?

时间:2014-09-07 16:35:32

标签: python matlab file-io numpy mat-file

我有一些变量,包括字典,列表列表和numpy数组。我使用以下代码保存所有代码,其中obj = [var1,var2,...,varn]。变量大小足够小,可以加载到内存中。

我的问题是当我在matlab中保存相应的变量时,输出文件占用的磁盘空间比在python中少得多。类似地,从磁盘加载变量需要花费更多的时间在python中加载到内存中而不是matlab。

with open(filename, 'wb') as output:
    pickle.dump(obj, output, pickle.HIGHEST_PROTOCOL)

由于

3 个答案:

答案 0 :(得分:1)

Matlab使用HDF5和压缩来保存mat-Files; HDF5是一种非常快速地访问大量数据的格式。 Python-pickle保护信息以重新创建对象,它没有针对速度和大小进行优化,而是灵活性。 如果你愿意,可以使用HDF5进行python。

答案 1 :(得分:1)

试试这个:

保存到磁盘

import gzip
gz = gzip.open(filename + '.gz', 'wb')
gz.write(pickle.dumps(obj, pickle.HIGHEST_PROTOCOL))
gz.close()

从磁盘加载

import gzip
gz = gzip.open(filename + '.gz', 'rb')
obj = pickle.loads(gz.read())
gz.close()

答案 2 :(得分:0)

嗯,问题在于pickle而不是Python本身。正如其他人所提到的,.mat文件保存在7.3或更高版本中,使用HDF5格式。 HDF5经过优化,可有效存储和检索大型数据集; Pickle处理数据的方式不同。您可以使用h5py或netcf4 Python模块复制甚至超越Matlab保存功能的性能; NetCDF是HDF5的子集。例如,使用HDF5,您可以:

import h5py
import numpy as np

f = h5py.File('test.hdf5','w')
a = np.arange(10)
dset = f.create_dataset("init", data=a)
f.close()

我不确定在MATLAB中执行等效操作是否会导致文件大小完全相同但应该接近。您可以使用HDF5的压缩功能来获得所需的结果。

编辑1:

要加载HDF5文件,例如.mat文件,您可以执行M2 = h5py.File('file.mat')之类的操作。 M2是一个HDF5组,有点像python字典。执行M2.keys()会为您提供变量名称。如果其中一个变量是一个名为“data”的数组,则可以通过执行data = M2["data"][:]来读出它。

编辑2:

要保存多个变量,您可以创建多个datasets。基本语法是f.create_dataset("variable_name", data=variable)。请参阅链接以获取更多选项例如,

import h5py
import numpy as np

f = h5py.File('test.hdf5','w')

data1 = np.ones((4,4))
data2 = 2*data1
f.create_dataset("ones", data=data1)
f.create_dataset("twos", data=data2)

f既是文件对象又是HDF5组。所以做f.keys()会给出:

[u'ones', u'twos']

要查看存储在'ones'键下的内容,您可以执行以下操作:

f['ones'][:]

array([[ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.]])

您可以根据需要创建任意数量的数据集。完成文件编写后,关闭文件对象:f.close()

我应该补充一点,我的方法仅适用于类似数组的数据集。您可以保存其他Python对象,例如列表和词典,但这样做需要更多的工作。我只使用HDF5来处理大型numpy阵列。对于其他一切,pickle对我来说效果很好。