我最初问了一个相关的问题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-class或http://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