Scipy查找稀疏矩阵中每行最小非零元素

hkmswyz6  于 2022-11-10  发布在  其他
关注(0)|答案(2)|浏览(122)

我试图找出稀疏矩阵中每一行的最小元素的位置和值。下面给出了一个简单的例子:这里,我们有一个3x 6的稀疏矩阵“M.”

H = np.array([[1, 2, 3, 0, 4, 0 ,0],
              [0, 5, 0, 6, 0, 0 ,0],
              [0, 0, 0, 7, 0, 0 ,8], dtype = np.float32)
M = scipy.sparse.csr_matrix(H)

然后,我想得到的是每一行的非零最小元素。对于上面的例子:

min_elements = some_function(M,axis = 0)

方法M.min(axis=0)不适用于我的情况,因为每行的最小元素都是零,因此返回全零数组。
因此,有没有一种有效的方法可以使用稀疏矩阵以计算效率高的方式实现这样的功能。在我的一般情况下,稀疏矩阵将非常巨大,需要大量的额外计算。因此,性能/速度是我的主要基准。
谢谢你,谢谢你

55ooxyrt

55ooxyrt1#

In [333]: from scipy import sparse

In [334]: M = sparse.csr_matrix(H)    
In [335]: M
Out[335]: 
<3x7 sparse matrix of type '<class 'numpy.float32'>'
    with 8 stored elements in Compressed Sparse Row format>

M存储为:

In [336]: M.indptr
Out[336]: array([0, 4, 6, 8], dtype=int32)    
In [337]: M.data
Out[337]: array([1., 2., 3., 4., 5., 6., 7., 8.], dtype=float32)    
In [338]: M.indices
Out[338]: array([0, 1, 2, 4, 1, 3, 3, 6], dtype=int32)

我们可以在由indptr定义的切片上迭代,并取min:

In [340]: for i in range(M.shape[0]):
     ...:     sl = slice(M.indptr[i],M.indptr[i+1])
     ...:     x, y = M.data[sl], M.indices[sl]
     ...:     m = np.argmin(x)
     ...:     print(y[m], x[m])
     ...:     
0 1.0
1 5.0
3 7.0

这可以简化一点,但它给出了基本的想法。
lil来描述所发生的事情可能更容易:

In [341]: Ml = M.tolil()

In [342]: Ml.data
Out[342]: 
array([list([1.0, 2.0, 3.0, 4.0]), list([5.0, 6.0]), list([7.0, 8.0])],
      dtype=object)
In [343]: Ml.rows
Out[343]: array([list([0, 1, 2, 4]), list([1, 3]), list([3, 6])], dtype=object)

In [344]: for d,r in zip(Ml.data, Ml.rows):
     ...:     m = np.argmin(d)
     ...:     print(r[m], d[m])
     ...:     
0 1.0
1 5.0
3 7.0

以前的SO要求按行提供最小(或最大)N值。
稀疏矩阵最适合用矩阵乘法来表示,包括行(或列)和,甚至csr索引也是用矩阵乘法来完成的,其他的逐行运算就不那么容易了。

l7mqbcuq

l7mqbcuq2#

你可以翻转所有的数据,找到最大值。这是假设你所有的数据都是正数,就像例子中的那样。

M_inv = M.copy()
M_inv.data = 1/M.data
one_over_min_M = M_inv.max(axis=1)

min_M = 1/one_over_min_M.to_array()

在您的示例中,我得到了输出

[[1.       ]
 [5.       ]
 [6.9999995]]

这里有一些可怕的数字错误,但如果你愿意round你的答案...
编辑:如果你在追求指数,并想做M_inv.argmax(axis=1),这种方法可能是可取的,否则它可能不是最好的。

相关问题