简体   繁体   English

没有scipy.sparse的矢量化稀疏和

[英]Vectorize sparse sum without scipy.sparse

I am trying to do spatial derivatives and almost managed to get all the loops out of my code, but when I try to sum everything up at the end I have a problem. 我正在尝试做空间衍生物,并且几乎设法从我的代码中获取所有循环,但是当我尝试在最后总结一切时我有一个问题。

I have a set of N~=250k nodes. 我有一组N~=250k节点。 I have found indices i,j of node pairs with i.size=j.size=~7.5M that are within a certain search distance, originally coming from np.triu_indices(n,1) and passed through a series of boolean masks to wash out nodes not influencing each other. 我找到了i.size=j.size=~7.5M的节点对的索引i,j ,它们在一定的搜索距离内,最初来自np.triu_indices(n,1)并通过一系列布尔掩码传递给清除不影响彼此的节点。 Now I want to sum up the influences on each node from the other nodes. 现在我想总结一下其他节点对每个节点的影响。

I currently have this: 我目前有这个:

def sparseSum(a,i,j,n):
    return np.array([np.sum(a[np.logical_or(i==k,j==k)],axis=0) for k in range(n)])

This is very slow. 这很慢。 What I would like is something vectorized. 我想要的是矢量化的东西。 If I had scipy I could do 如果我有scipy,我可以做

def sparseSum(a,i,j,n):
    sp=scipy.sparse.csr_matrix((a,(i,j)),shape=(n,n))+ scipy.sparse.csr_matrix((a,(j,i)),shape=(n,n))
    return np.sum(sp, axis=0)

But I'm doing this all within an Abaqus implementation that doesn't include scipy. 但是我在Abaqus实现中完成了这一切,不包括scipy。 Is there any way to do this numpy-only? 有没有办法只做这个numpy?

Approach #1 : Here's an approach making use of matrix-multiplication and broadcasting - 方法#1:这是一种利用matrix-multiplicationbroadcasting -

K = np.arange(n)[:,None]
mask = (i == K) | (j == K)
out = np.dot(mask,a)

Approach #2 : For cases with a small number of columns, we can use np.bincount for such bin-based summing along each column, like so - 方法#2:对于列数较少的情况,我们可以使用np.bincount对每列进行基于bin的求和,如下所示 -

def sparseSum(a,i,j,n):
    if len(a.shape)==1:
        out=np.bincount(i,a,minlength=n)+np.bincount(j,a)
    else:
        ncols = a.shape[1]
        out = np.empty((n,ncols))
        for k in range(ncols):
            out[:,k] = np.bincount(i,a[:,k],minlength=n) + np.bincount(j,a[:,k])
    return out

Here's not a turn-key solution but one that adds columns of a sparse matrix. 这里不是一个交钥匙解决方案,而是一个添加稀疏矩阵列的解决方案。 It essentially computes and utilises the csc representation 它主要计算和利用csc表示

def sparse_col_sums(i, j, a, N):
    order = np.lexsort(j, i)
    io, jo, ao = i[order], j[order], a[order]
    col_bnds = io.searchsorted(np.arange(N))
    return np.add.reduceat(ao, col_bnds)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM