【问题标题】:Boolean operations on scipy.sparse matricesscipy.sparse 矩阵上的布尔运算
【发布时间】:2013-01-08 19:06:32
【问题描述】:

我有一组填充了布尔值的稀疏矩阵,我需要对这些矩阵执行逻辑运算(主要是按元素或)。

在 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>

数据类型更改为“int8”,这会导致以后的操作出现问题。这可以通过以下方式解决:

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

但我的印象是,所有这些类型的更改都会导致性能下降。

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

【问题讨论】:

    标签: python scipy sparse-matrix


    【解决方案1】:

    稀疏矩阵不支持逻辑运算,但转换回“布尔”并不是那么昂贵。实际上,如果使用 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
    

    【讨论】:

      【解决方案2】:

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

      a.multiply(b) #AND
      a+b           #OR
      (a>b)+(a<b)   #XOR
      a>b           #NOT
      

      所以布尔运算支持的。

      【讨论】:

      • 我正在寻找一种表达异或的方法,谢谢!顺便说一句,这是因为在 Python 中 False &lt; True 被认为是真的,False &lt; False 被认为是假的等等......
      猜你喜欢
      • 2011-07-22
      • 2015-06-17
      • 2021-09-26
      • 1970-01-01
      • 2015-12-22
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多