我有结构化数据,可以用numpy
表示,如下所示:
dtype = np.dtype([('a', 'f8'),
('b', 'f8')])
X = np.zeros((3,4), dtype=dtype)
并希望在它的稀疏版本上运行。 Scipy有sparse
,但我还没有弄明白如何实现结构化数据:
import numpy as np
import scipy.sparse as sparse
dtype = np.dtype([('a', 'f8'),
('b', 'f8')])
X = np.zeros((3,4), dtype=dtype)
A, B = X['a'], X['b']
A[:] = np.arange(0, 12).reshape((3,4))
Xdok = sparse.dok_matrix(X, dtype=dtype)
Xcoo = Xdoc.tocoo()
# No supported conversion for structured type
# Xcsr = Xdok.tocsr()
# Xlil = Xdok.tolil()
# Cannot perform reduce with flexible type
# Xdok['a']
# 'coo_matrix' object is not subscriptable
# Xcoo['a']
我可以获得doc
和coo
版本,但之后我无法切出我的密钥(例如Xdok['a']
),而且根据我的理解,{{1并且dok
在执行任何类型的数学运算时都是低效的。
最终,我试图用边缘上的多值权重来表示有向图(例如coo
和a
),我需要能够执行简单的线性代数图表。
我考虑将b
稀疏矩阵与a
稀疏矩阵分开,但最终它们将填充在完全相同的索引中,我宁愿保留所有内存中一个结构中的数据。
我应该使用另一个lib而不是Scipy吗?
答案 0 :(得分:1)
In [26]: M = sparse.coo_matrix(X)
In [27]: M.data
Out[27]:
array([( 1., 0.), ( 2., 0.), ( 3., 0.), ( 4., 0.), ( 5., 0.), ( 6., 0.),
( 7., 0.), ( 8., 0.), ( 9., 0.), (10., 0.), (11., 0.)],
dtype=[('a', '<f8'), ('b', '<f8')])
In [28]: M.A
....
ValueError: unsupported data types in input
In [30]: M.tocsr()
...
TypeError: no supported conversion for types: (dtype([('a', '<f8'), ('b', '<f8')]),)
使用化合物dtype转换为(和来自)dok
:
In [31]: M.todok()
Out[31]:
<3x4 sparse matrix of type '<class 'numpy.void'>'
with 11 stored elements in Dictionary Of Keys format>
In [32]: _.items()
Out[32]: dict_items([((0, 1), (1., 0.)), ((1, 2), (6., 0.)), ((1, 3), (7., 0.)), ((2, 3), (11., 0.)), ((2, 0), (8., 0.)), ((1, 0), (4., 0.)), ((0, 3), (3., 0.)), ((2, 2), (10., 0.)), ((1, 1), (5., 0.)), ((2, 1), (9., 0.)), ((0, 2), (2., 0.))])
dok
实现索引:
In [33]: __[0,1]
Out[33]: (1., 0.)
M.data
数组是结构化的,可以通过字段名称访问。但coo
尚未实施任何索引:
In [34]: M.data['a']
Out[34]: array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11.])
dok
是字典的子类,显然元素存储为dtype记录:
In [39]: type(M.todok()[0,1])
Out[39]: numpy.void
In [40]: M.todok()[0,1]['a']
Out[40]: 1.0
但同样,dok
索引中没有用于访问字段的规定。
总而言之,稀疏模块并未考虑复合dtypes。它的根源是线性代数(例如求解大型稀疏线性方程)。这些dtypes工作的地方就是使用numpy
数组和元素而无需特殊处理。