如何对稀疏矩阵进行< =和> =?

时间:2018-05-16 17:34:08

标签: python numpy scipy sparse-matrix

是否可以在Scipy稀疏矩阵上执行< =或> =操作,这样如果所有相应元素的操作都为真,则表达式返回True?例如,< = b表示对于矩阵(A,B)中的所有对应元素(a,b),a< = b?这是一个需要考虑的例子:

import numpy as np
from scipy.sparse import csr_matrix

np.random.seed(0)
mat = csr_matrix(np.random.rand(10, 12)>0.7, dtype=int)
print(mat.A)
print()

np.random.seed(1)
matb = csr_matrix(np.random.rand(10, 12)>0.7, dtype=int)
print(matb.A)

运行此操作会发出警告:SparseEfficiencyWarning: Comparing sparse matrices using >= and <= is inefficient, using <, >, or !=, instead并提供错误:ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all().

我希望能够获取2个稀疏矩阵A和B,并确定(A,B)中每对相应元素(a,b)的A&lt; = B.这可能吗?这种操作的表现会是什么?

2 个答案:

答案 0 :(得分:1)

In [402]: np.random.seed = 0
     ...: mat = sparse.csr_matrix(np.random.rand(10, 12)>0.7, dtype=int)
In [403]: mat
Out[403]: 
<10x12 sparse matrix of type '<class 'numpy.int64'>'
    with 40 stored elements in Compressed Sparse Row format>
In [404]: mat.A
Out[404]: 
array([[1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0],
       [1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0],
       ...
       [0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1],
       [0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]], dtype=int64)
In [405]: np.random.seed = 1
     ...: matb = sparse.csr_matrix(np.random.rand(10, 12)>0.7, dtype=int)

In [407]: mat<matb
Out[407]: 
<10x12 sparse matrix of type '<class 'numpy.bool_'>'
    with 27 stored elements in Compressed Sparse Row format>
In [408]: mat>=matb
/home/paul/.local/lib/python3.6/site-packages/scipy/sparse/compressed.py:295: SparseEfficiencyWarning: Comparing sparse matrices using >= and <= is inefficient, using <, >, or !=, instead.
  "using <, >, or !=, instead.", SparseEfficiencyWarning)
Out[408]: 
<10x12 sparse matrix of type '<class 'numpy.float64'>'
    with 93 stored elements in Compressed Sparse Row format>

在您的情况下,matmatb都不是特别稀疏,40和36非零可能是120.即便如此,mat<matb会产生27个非零(True)值,而>=测试结果为93.两个矩阵都为0时,结果为True。

警告我们,如果我们进行这种测试,使用稀疏矩阵不会节省空间或时间(与密集阵列相比)。它不会杀死我们,它只是效率不高。

答案 1 :(得分:0)

(为这个答案拉一些评论):

要简单地在两个稀疏矩阵A和B上执行elementwise&lt; =,您可以执行(A&lt; = B)。然而,正如@hpaulj指出的那样,这是低效的,因为任何一对相应的0元素(即(1)和B中的(1,1)都是0)将通过该操作变为1。假设A和B都是稀疏的(大多数是0),你将通过使它们大部分为1来破坏它们的稀疏性。

要解决此问题,请考虑以下事项:

A = csr_matrix((3, 3))
A[1, 1] = 1
print(A.A)
print()

B = csr_matrix((3, 3))
B[0, 0] = 1
B[1, 1] = 2
print(B.A)

print(not (A > B).count_nonzero())

要解释最后一行,A > B将与A <= B相反,因此相应的0将保持为0,并且a > b将成为1的任何位置。因此,如果得到的矩阵具有任何非零元素,这意味着在(A,B)中存在一些(a,b),其中a> 1。湾这意味着 A&lt; = B(元素)的情况。