所以让我们创建你的矩阵(可惜你没有给出我可以复制粘贴的输入)In [114]: data=[4,1,2,2,1,1,4,3,2]
In [115]: col=[0,1,1,2,2,3,4,4,4]
In [116]: row=[2,0,4,0,3,5,0,2,3]
In [117]: M=sparse.csr_matrix((data,(col,row)))
In [118]: M
Out[118]:
<5x6 sparse matrix of type ''
with 9 stored elements in Compressed Sparse Row format>
In [119]: M.A
Out[119]:
array([[0, 0, 4, 0, 0, 0],
[1, 0, 0, 0, 2, 0],
[2, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 1],
[4, 0, 3, 2, 0, 0]])
In [121]: center=np.array([[0,1,2,2,4,1],[3,4,1,2,4,0]])
那么你是如何计算距离的?M.A是(5,6),center是(2,6)。这两个数组的用途并不明显。在
至于对“原始”稀疏值的访问,coo格式最容易理解。这和我用来创建矩阵的行、列、数据一样
^{pr2}$
csr将相同的信息存储在data、indices和indptr数组中。但是您必须做一些数学运算才能从最后2个中提取i,j值。csr乘法例程很好地利用了这些数组。在
一般来说,与csr矩阵相乘比加法/减法好。在
我等待进一步的澄清。在spatial.distance.cdist(center,M.A, 'euclidean')
Out[156]:
array([[ 5.09901951, 3.87298335, 5.19615242, 5. , 5.91607978],
[ 7.34846923, 5.38516481, 5.91607978, 6.8556546 , 6.08276253]])
我们需要做的是研究这个函数,并理解它的输入。我们可能要超越它的文档,看看代码。在
但是看一下这段代码,我看到了一些步骤来确保xB是2d数组,列数与xA相同。然后对于euclidian,它调用_distance_wrap.cdist_euclidean_wrap(_convert_to_double(XA),
_convert_to_double(XB), dm)
看起来像是C语言的包装器。我无法想象有什么方法可以给它提供一个稀疏矩阵。在
您可以迭代行;使用M[[0],:].A调用dist与{}相同,只是速度不同。迭代稀疏矩阵的行有点慢,因为每次迭代都要构造一个新的稀疏矩阵。csr和{}是行迭代最快的2个。在
下面是一些可能更快的方法-直接迭代lil格式的属性:def foo(a,b,n):
# make a dense array from data,row
res = np.zeros((1,n))
res[0,b]=a
return res
In [190]: Ml=M.tolil()
In [191]: Ml.data
Out[191]: array([[4], [1, 2], [2, 1], [1], [4, 3, 2]], dtype=object)
In [192]: Ml.rows
Out[192]: array([[2], [0, 4], [0, 3], [5], [0, 2, 3]], dtype=object)
In [193]: rowgen=(foo(a,b,6) for a,b in zip(Ml.data,Ml.rows))
In [194]: np.concatenate([spatial.distance.cdist(center,row, 'euclidean') for row in rowgen],axis=1)
Out[194]:
array([[ 5.09901951, 3.87298335, 5.19615242, 5. , 5.91607978],
[ 7.34846923, 5.38516481, 5.91607978, 6.8556546 , 6.08276253]])
现在我跳过时间测试。在