【问题标题】:Loading Matlab sparse matrix using Python Pytables使用 Python Pytables 加载 Matlab 稀疏矩阵
【发布时间】:2012-01-16 21:20:30
【问题描述】:

我最初问了一个相关问题here,但似乎并没有真正得到任何结果。也许如果我更具体地改写其中的一部分,它可能会有所帮助....

我使用 Matlab 的稀疏格式(HDF5、csc I 相信),我正在尝试使用 Pytables 直接对它们进行操作, 但还没有成功。使用 h5py 我可以做到以下几点:

# Method 1: uses h5py (WORKS)
f1 = h5py.File(fname)
data = f1['M']['data']
ir = f1['M']['ir']
jc = f1['M']['jc']
M = scipy.sparse.csc_matrix((data, ir, jc))

但如果我尝试在 Pytables 中做同样的事情:

# Method 2: uses pyTables (DOESN'T WORK)
f2 = tables.openFile(fname)
data = f2.root.M.data
ir = f2.root.M.ir
jc = f2.root.M.jc
M = scipy.sparse.csc_matrix( (data,ir,jc) )

这失败(经过长时间的等待)并出现错误:

TypeError                                 Traceback (most recent call last)

/home/tdiethe/BMJ/<ipython console> in <module>()

/usr/lib/python2.6/dist-packages/scipy/sparse/compressed.pyc in __init__(self, arg1, shape, dtype, copy, dims, nzmax)
    56                     self.indices = np.array(indices, copy=copy)
    57                     self.indptr  = np.array(indptr, copy=copy)
---> 58                     self.data    = np.array(data, copy=copy, dtype=getdtype(dtype, data))
    59                 else:
    60                     raise ValueError, "unrecognized %s_matrix constructor usage" %\

/usr/lib/python2.6/dist-packages/scipy/sparse/sputils.pyc in getdtype(dtype, a, default)
    69                 canCast = False
    70             else:
---> 71                 raise TypeError, "could not interpret data type"
    72     else:
    73         newdtype = np.dtype(dtype)

TypeError: could not interpret data type

看着f2

In [63]: f2.root.M.data
Out[63]: 
/M/data (CArray(4753606,), zlib(3)) ''
  atom := Float64Atom(shape=(), dflt=0.0)
  maindim := 0
  flavor := 'numpy'
  byteorder := 'little'
  chunkshape := (8181,)

In [64]: f2.root.M.ir
Out[64]: 
/M/ir (CArray(4753606,), zlib(3)) ''
  atom := UInt64Atom(shape=(), dflt=0)
  maindim := 0
  flavor := 'numpy'
  byteorder := 'little'
  chunkshape := (8181,)

In [65]: f2.root.M.jc
Out[65]: 
/M/jc (CArray(133339,), zlib(3)) ''
  atom := UInt64Atom(shape=(), dflt=0)
  maindim := 0
  flavor := 'numpy'
  byteorder := 'little'
  chunkshape := (7843,)

我有两个问题:

  • 如何使用 pytables 加载此文件
  • 我是否需要转换为 scipy 稀疏矩阵才能对其执行操作,或者我可以直接对磁盘文件执行操作(矩阵乘法等...) - 即无需加载文件进入内存(如果不是,那么使用 pytables 有什么意义?)?

【问题讨论】:

  • 这些错误来自 scipy。你能检查一下说只是 numpy 对datairjc 进行操作的能力吗? numpy 对数据有什么看法(即 dtype、shape 等)?结果是你所期望的吗?它们是否与 scipy.sparse.csc_matrix 中对该调用签名的预期相符?
  • 啊,是的,看来我所要做的就是:M = sparse.csc_matrix( (f2.root.M.data[...], f2.root.M.ir[...], f2.root.M.jc[...]) ) 还不确定第二个问题吗? PyTables 上似乎只有元素操作可用?

标签: python matlab numpy scipy sparse-matrix


【解决方案1】:

我错过了在您的原始帖子中看到这一点,但我认为您的问题在于 PyTables 的设计,它在基础数据之上提供了额外的抽象级别。

考虑以下几点:

>>> import tables
>>> import numpy as np

>>> h5_file = tables.openFile(fname)
>>> data = f2.root.M.data

此时data 不是numpy 数组:

>>> type(data)
tables.array.Array

>>> isinstance(data, np.ndarray)
False

tables.array.Array 会立即加载底层数组,或立即公开类似数组的功能。当您尝试使用这些类型的对象在scipy 中创建稀疏数组时,这就是导致错误的原因。

相反,PyTables 生成的 data 对象旨在通过其他命令提供对数据的访问(即您通过使用花哨的索引 [...] 做到了这一点)。在这种方法中,您可以通过data[:]data.read() 访问部分数据或全部数据。到此,我们熟悉的numpy数组就产生了。

有关tables.array.Array 类的更多信息,请参阅http://pytables.github.com/usersguide/libref.html#the-array-classhttp://www.pytables.org/moin/HowToUseGetting actual data 部分,了解访问基础数据的示例。

相比之下,pyh5 产生了更多类似数组的对象,尽管仍然不是numpy 数组。考虑:

>>> import pyh5
>>> f1 = h5py.File(fname)
>>> data = f1['M']['data']
>>> type(data)
h5py._hl.dataset.Dataset
>>> isinstance(data, np.ndarray)
>>> False

但是,您可以立即对data 执行numpy 操作,就像调用scipy 一样,或者更简单的操作,例如np.cos(data)data + np.arange(len(data))。似乎data 对象具有一些熟悉的numpy 类属性(即shape),并且基础数据(numpy.ndarray)存储在data.value。但是,我对pyh5 并不熟悉,因为我自己没有使用过它,所以我不确定这方面的限制是什么。

一般来说,PyTablespyh5 似乎有不同的设计目标,因此应该以不同的方式使用。 pyh5 为 HDF 文件提供了更类似于 Numpy 的接口,而PyTables 提供了更复杂的数据库之类的操作。请参阅pyh5PyTables 文档和 Enthought 邮件列表中对差异的讨论:

【讨论】:

  • 非常有用的答案谢谢。慢慢掌握这个!我认为 PyTables 将为我们的项目提供一些有用的功能,因为可扩展性很重要。
猜你喜欢
  • 1970-01-01
  • 2022-08-18
  • 2013-04-11
  • 1970-01-01
  • 2014-11-01
  • 2017-07-02
  • 2012-07-28
  • 2012-06-20
  • 1970-01-01
相关资源
最近更新 更多