numpy.any(axis=i) 用于 scipy.sparse

问题描述

import numpy
a = numpy.array([
    [0,1,0],[1,[0,])
numpy.any(a,axis=0)
numpy.any(a,axis=1)

生产

array([ True,True,False])
array([ True,False,False])

不过之后

from scipy import sparse
a = sparse.csr_matrix(a)

相同的 numpy.any(a,axis) 调用产生

<5x4 sparse matrix of type '<class 'numpy.intc'>'
        with 3 stored elements in Compressed Sparse Row format>

Traceback (most recent call last):
  File "<stdin>",line 1,in <module>
  File "<__array_function__ internals>",line 5,in any
  File "C:\Users\user\.conda\envs\py385\lib\site-packages\numpy\core\fromnumeric.py",line 2330,in any
    return _wrapreduction(a,np.logical_or,'any',axis,None,out,keepdims=keepdims)
  File "C:\Users\user\.conda\envs\py385\lib\site-packages\numpy\core\fromnumeric.py",line 87,in _wrapreduction
    return ufunc.reduce(obj,dtype,**passkwargs)
numpy.AxisError: axis 1 is out of bounds for array of dimension 0

当然,a 实际上是一个非常大的稀疏矩阵,转换为普通的 numpy 数组不是一种选择。我如何为 csr_matrix 和其他 scipy.sparse 矩阵获得相同(或等效)的结果?

添加

根据Usage information in official scipy documentation

尽管它们与 NumPy 数组相似,强烈不鼓励直接在这些矩阵上使用 NumPy 函数,因为 NumPy 可能无法正确转换它们以进行计算,从而导致意外(和不正确)的结果。如果您确实想将 NumPy 函数应用于这些矩阵,请首先检查 SciPy 是否对给定的稀疏矩阵类有自己的实现,或者将稀疏矩阵转换为 NumPy 数组(例如,使用 toarray() 类的方法),然后再应用该方法

我正在寻找“它自己的实现”或等效的。

解决方法

你可以在 bool 数组上使用 sum 而不是 any

import numpy
a = numpy.array([
    [0,1,0],[1,[0,])

from scipy import sparse
a = sparse.csr_matrix(a.astype(bool))
# Use sum instead of any on a bool array
print(a.sum(axis=0).astype(bool))
print(a.sum(axis=1).flatten().astype(bool))

输出:

[[ True  True  True False]]
[[ True  True  True False False]]

如果你想做“所有”,那会有点棘手,因为 scipy 似乎没有“prod”的实现。 但 this post 对此案有答案。