from scipy import sparse
from scipy.sparse import csc_matrix
r,c,v = sparse.find(a) # a is input sparse matrix
out = np.zeros(a.shape[0],dtype=a.dtype)
unqr, shift_idx = np.unique(r,return_index=1)
out[unqr] = np.multiply.reduceat(v, shift_idx)
样品运行 -
In [89]: # Let's create a sample csc_matrix
...: A = np.array([[-1,2,0,0],[0,0,0,0],[2,0,3,0],[4,5,6,0],[1,9,0,2]])
...: a = csc_matrix(A)
...:
In [90]: a
Out[90]:
<5x4 sparse matrix of type '<type 'numpy.int64'>'
with 10 stored elements in Compressed Sparse Column format>
In [91]: a.toarray()
Out[91]:
array([[-1, 2, 0, 0],
[ 0, 0, 0, 0],
[ 2, 0, 3, 0],
[ 4, 5, 6, 0],
[ 1, 9, 0, 2]])
In [92]: out
Out[92]: array([ -2, 0, 6, 120, 0, 18])
Approach #2: 我们正在执行基于bin的乘法 . 我们有np.bincount的基于bin的求和解决方案 . 因此,这里可以使用的技巧是将数字转换为对数,执行基于bin的求和,然后使用 exponential (日志的反向)转换回原始格式,并且's it! For negative numbers, we might to add a step or more, but let'看到非实现的情况负数 -
3 回答
Approach #1: 我们可以使用稀疏元素的行索引作为ID,并使用np.multiply.reduceat执行这些元素的相应值的乘法,以获得所需的输出 .
因此,实施将是 -
样品运行 -
Approach #2: 我们正在执行基于bin的乘法 . 我们有np.bincount的基于bin的求和解决方案 . 因此,这里可以使用的技巧是将数字转换为对数,执行基于bin的求和,然后使用
exponential
(日志的反向)转换回原始格式,并且's it! For negative numbers, we might to add a step or more, but let'看到非实现的情况负数 -运行非负数的样本 -
做一个样本:
在
lil
格式中,每行的值存储在列表中 .拿这些产品:
在
csr
格式中,值存储为:indptr
给出行值的开头 .csr
(和csc
)矩阵上的计算代码通常执行这样的计算(但已编译):使用Diavaker的测试矩阵:
上面的循环产生:
Divakar的代码
unique
和reduceat
(空行的不同值) .
使用
indptr
简化Reduceat只是:需要修复空第2行的值(
indptr
值为[2,2,...],reduceat
使用M.data[2]
) .有一个更大的矩阵
这个
wptr
比Divaker的版本快30倍 .关于跨稀疏矩阵的行计算值的更多讨论:Scipy.sparse.csr_matrix: How to get top ten values and indices?
您可以使用numpy模块中的prod()方法计算A的每个子列表中所有元素的乘积,同时排除值0的元素 .