2013-01-24 54 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