使用Python Pytables加载Matlab稀疏矩阵

我最初问了一个相关的问题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加载此文件
>是否需要执行到稀疏矩阵的转换才能对其执行操作,还是可以直接在磁盘文件上执行操作(矩阵乘法等…)-即不将文件加载到内存中(如果不是,使用pytables有什么意义?)?

解决方法:

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

考虑以下:

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

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

此时,数据不是numpy数组:

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

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

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

而是由PyTables生成的数据对象旨在通过其他命令提供对数据的访问(即,您通过使用花哨的索引进行了访问).通过这种方法,您可以通过执行data [:]或data.read()来访问部分数据或全部数据.仅在这一点上,才生成熟悉的numpy数组.

有关tables.array.Array类的更多信息,请参见http://pytables.github.com/usersguide/libref.html#the-array-classhttp://www.pytables.org/moin/HowToUse的获取实际数据部分,以获取访问基础数据的示例.

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

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

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

通常,PyTables和pyh5具有不同的设计目标,因此应以不同的方式使用. pyh5为HDF文件提供了更类似于Numpy的界面,而PyTables提供了更为复杂的数据库,如操作.请参阅pyh5,PyTables文档和Enthought邮件列表中有关差异的讨论:

> http://code.google.com/p/h5py/wiki/FAQ#What’s_the_difference_between_h5py_and_PyTables_?
> http://www.pytables.org/moin/FAQ#HowdoesPyTablescomparewiththeh5pyproject.3F
> https://mail.enthought.com/pipermail/enthought-dev/2010-November/027506.html

上一篇:python-分组的熊猫DataFrames:如何将scipy.stats.sem应用于它们?


下一篇:在SciPy安装中忽略ARCHFLAGS的Pip / easy_install吗?