为什么在Python中保存/加载数据比在Matlab中占用更多空间/时间?

0 投票
3 回答
2421 浏览
提问于 2025-04-20 07:29

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

我的问题是,当我在matlab中保存这些变量时,输出文件占用的磁盘空间比在python中少得多。同样,从磁盘加载变量到内存的时间,在python中也比在matlab中要长得多。

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

谢谢

3 个回答

0

这个问题主要是关于pickle,而不是Python本身。正如其他人提到的,版本7.3或更高的.mat文件使用的是HDF5格式。HDF5格式是为了高效存储和提取大数据集而优化的;而pickle处理数据的方式则不同。你可以通过使用h5py或netcdf4这两个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:

要保存多个变量,你可以创建多个数据集。基本语法是f.create_dataset("变量名", data=变量)。更多选项可以查看链接。例如:

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对象,比如列表和字典,但这样做需要更多的工作。我通常只在处理大型numpy数组时才使用HDF5。对于其他情况,pickle对我来说就足够了。

1

Matlab使用HDF5格式和压缩技术来保存mat文件;HDF5是一种可以快速访问大量数据的格式。Python的pickle功能则是用来保存信息,以便以后重新创建对象,它并不是为了速度和文件大小进行优化,而是为了灵活性。如果你愿意的话,可以在Python中使用HDF5。

2

试试这个:

要保存到磁盘上

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()

撰写回答