2013-01-24 53 views
8

我有一组填充布尔值的稀疏矩阵,我需要在其上执行逻辑运算(主要是元素OR)。对scipy.sparse矩阵的布尔操作

如numpy的,求和与D型细胞=“布尔”矩阵给出逐元素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> 

的数据类型被更改为“INT8”,这会导致未来运营的问题。这可以通过说:

(a+b).astype('bool') 

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

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

回答

5

稀疏矩阵不支持逻辑操作,但转换回'布尔'并不是那么昂贵。其实,如果使用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 

您可能已经注意到,您的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 

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