scipy.sparse矩阵的布尔运算

The*_*ONP 10 python scipy sparse-matrix

我有一组稀疏矩阵填充了布尔值,我需要执行逻辑运算(主要是元素方式OR).

如同在numpy中,用dtype ='bool'求和矩阵给出了元素的OR,但是有一个令人讨厌的副作用:

>>> from scipy import sparse
>>> [a,b] = [sparse.rand(5,5,density=0.1,format='lil').astype('bool')
...  for x in range(2)]
>>> b
<5x5 sparse matrix of type '<class 'numpy.bool_'>'
    with 2 stored elements in LInked List format>
>>> a+b
<5x5 sparse matrix of type '<class 'numpy.int8'>'
    with 4 stored elements in Compressed Sparse Row format>
Run Code Online (Sandbox Code Playgroud)

数据类型更改为"int8",这会导致将来的操作出现问题.这可以通过以下方式得到解决:

(a+b).astype('bool')
Run Code Online (Sandbox Code Playgroud)

但我得到的印象是,所有这种类型的改变都会导致性能下降.

为什么结果的dtype与操作数不同?
有没有更好的方法在python中对稀疏矩阵进行逻辑运算?

Rad*_*led 7

您可以通过以下方式轻松表达布尔运算。然后它适用于稀疏矩阵。

a.multiply(b) #AND
a+b           #OR
(a>b)+(a<b)   #XOR
a>b           #NOT
Run Code Online (Sandbox Code Playgroud)

所以支持布尔运算


Jai*_*ime 5

稀疏矩阵不支持逻辑运算,但转换回'bool'并不是那么昂贵.实际上,如果使用LIL格式矩阵,由于性能波动,转换可能会显示为负时间:

a = scipy.sparse.rand(10000, 10000, density=0.001, format='lil').astype('bool')
b = scipy.sparse.rand(10000, 10000, density=0.001, format='lil').astype('bool')

In [2]: %timeit a+b
10 loops, best of 3: 61.2 ms per loop

In [3]: %timeit (a+b).astype('bool')
10 loops, best of 3: 60.4 ms per loop
Run Code Online (Sandbox Code Playgroud)

您可能已经注意到,在将LIL矩阵添加到一起之前,它们已转换为CSR格式,请查看返回格式.如果您已经开始使用CSR格式,那么转换开销会变得更加明显:

In [14]: %timeit a+b
100 loops, best of 3: 2.28 ms per loop

In [15]: %timeit (a+b).astype(bool)
100 loops, best of 3: 2.96 ms per loop
Run Code Online (Sandbox Code Playgroud)

CSR(和CSC)矩阵的data属性是一维数组,它保存稀疏矩阵的实际非零项,因此重构稀疏矩阵的成本将取决于矩阵的非零项数,而不是它的大小:

a = scipy.sparse.rand(10000, 10000, density=0.0005, format='csr').astype('int8')
b = scipy.sparse.rand(1000, 1000, density=0.5, format='csr').astype('int8')

In [4]: %timeit a.astype('bool') # a is 10,000x10,000 with 50,000 non-zero entries
10000 loops, best of 3: 93.3 us per loop

In [5]: %timeit b.astype('bool') # b is 1,000x1,000 with 500,000 non-zero entries
1000 loops, best of 3: 1.7 ms per loop
Run Code Online (Sandbox Code Playgroud)