将使用-v7.3(HDF5)保存的Matlab稀疏矩阵加载到Python中并对其进行操作

Posted

技术标签:

【中文标题】将使用-v7.3(HDF5)保存的Matlab稀疏矩阵加载到Python中并对其进行操作【英文标题】:Loading Matlab sparse matrix saved with -v7.3 (HDF5) into Python and operating on it 【发布时间】:2012-01-14 05:54:02 【问题描述】:

我是 python 新手,来自 matlab。我有一个以 matlab v7.3 (HDF5) 格式保存的大型稀疏矩阵。到目前为止,我已经找到了两种加载文件的方法,使用h5pytables。然而,在矩阵上操作似乎都非常慢。例如在matlab中:

>> whos     
  Name           Size                   Bytes  Class     Attributes

  M      11337x133338            77124408  double    sparse    

>> tic, sum(M(:)); toc
Elapsed time is 0.086233 seconds.

使用表格:

t = time.time()
sum(f.root.M.data)
elapsed = time.time() - t
print elapsed
35.929461956

使用 h5py:

t = time.time()
sum(f["M"]["data"])
elapsed = time.time() - t
print elapsed

(我放弃了等待......)

[编辑]

基于来自@bpgergo 的cmets,我应该补充一点,我已经尝试将h5py (f) 加载的结果转换为numpy 数组或scipy 稀疏数组在以下两个方式:

from scipy import sparse
A = sparse.csc_matrix((f["M"]["data"], f["M"]["ir"], f["tfidf"]["jc"]))

data = numpy.asarray(f["M"]["data"])
ir = numpy.asarray(f["M"]["ir"])
jc = numpy.asarray(f["M"]["jc"])    
    A = sparse.coo_matrix(data, (ir, jc))

但是这两个操作也都非常慢。

这里有什么我遗漏的吗?

【问题讨论】:

【参考方案1】:

后人的最终答案:

import tables, warnings
from scipy import sparse

def load_sparse_matrix(fname) :
    warnings.simplefilter("ignore", UserWarning) 
    f = tables.openFile(fname)
    M = sparse.csc_matrix( (f.root.M.data[...], f.root.M.ir[...], f.root.M.jc[...]) )
    f.close()
    return M

【讨论】:

【参考方案2】:

您的大部分问题是您在有效的内存映射数组上使用 python sum(即它在磁盘上,而不是在内存中)。

首先,您将比较从磁盘读取内容所需的时间与从内存中读取内容所需的时间。如果您想与您在 matlab 中所做的比较,请先将数组加载到内存中。

其次,python 的内置 sum 对于 numpy 数组非常低效。 (或者,更确切地说,独立地遍历 numpy 数组的每个项目非常慢,这是 python 的内置 sum 正在做的事情。)使用 numpy.sum(yourarray)yourarray.sum() 代替 numpy 数组。

举个例子:

(使用h5py,因为我比较熟悉。)

import h5py
import numpy as np

f = h5py.File('yourfile.hdf', 'r')
dataset = f['/M/data']

# Load the entire array into memory, like you're doing for matlab...
data = np.empty(dataset.shape, dataset.dtype)
dataset.read_direct(data)

print data.sum() #Or alternately, "np.sum(data)"

【讨论】:

在 Matlab 中加载文件几乎是瞬时的( 好吧,没有你的文件我无法测试它,但实际上在 python 中加载数组也应该很快。您当前正在做的实际上并没有加载它。它重新定义了有效的内存映射数组。在任何语言中独立访问它都会非常慢,因为它主要是磁盘寻道。上面的示例代码仍然很慢吗?另外,看看 scipy.io.loadmat docs.scipy.org/doc/scipy/reference/generated/… ,虽然我不确定它是否支持稀疏数组。【参考方案3】:

你缺少 numpy http://www.scipy.org/NumPy_for_Matlab_Users

【讨论】:

还有线索吗?如果我这样做 M = numpy.asarray(f["M"]["data"]) 这似乎需要永远...... @tdc,我什至不知道您的代码中的 f 是什么。尝试咨询此页面:docs.scipy.org/doc/scipy/reference/generated/…。虽然我读到了,你仍然需要一个 HDF5 python 库来加载 v7.3 Matlab 文件。 也没有关于稀疏矩阵的内容 抱歉 f 是使用 h5py 加载的:f = h5py.File('filename.mat') Numpy 也可以处理sparse 矩阵。如果我理解正确,您甚至无法将 Matlab 格式文件加载到 numpy 矩阵中。在这种情况下,我真的建议就这个特定问题提出一个新问题(至少我对此无能为力)。我真希望你完成之后会好起来的。

以上是关于将使用-v7.3(HDF5)保存的Matlab稀疏矩阵加载到Python中并对其进行操作的主要内容,如果未能解决你的问题,请参考以下文章

在 Matlab 中转置 Python 创建的 HDF5 数据集

将 scipy 稀疏矩阵存储为 HDF5

MATLAB:.mat 版本之间的差异

HDF5 中的稀疏数组支持

在python中创建一个v7.3的.mat文件

在 HDF5 (PyTables) 中存储 numpy 稀疏矩阵