Based on work on recent sparse issues, for example. Extremely low row sum operation in sparse LIL matrix in Python
Here's how your problem can be solved with sparse matrices. The method can also be applied to dense ones. The idea is that a sparse sum implemented as a matrix product with a row (or column) of 1s. Sparse matrices are indexed slowly, but matrix product is good C code.
In this case, I'm going to build a multiplication matrix that has 1s for the rows that I want to sum, a different set of 1s for each entry in the dictionary.
Matrix example:
In [302]: A=np.arange(8*3).reshape(8,3) In [303]: M=sparse.csr_matrix(A)
Dictionary of choice
:
In [304]: dict={0:[0,1],1:[1,0,2],2:[2,1],3:[3,4,7]}
build a sparse matrix from this dictionary. This may not be the most effective way to build such a matrix, but this is enough to demonstrate the idea.
In [305]: r,c,d=[],[],[] In [306]: for i,col in dict.items(): c.extend(col) r.extend([i]*len(col)) d.extend([1]*len(col)) In [307]: r,c,d Out[307]: ([0, 0, 1, 1, 1, 2, 2, 3, 3, 3], [0, 1, 1, 0, 2, 2, 1, 3, 4, 7], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) In [308]: idx=sparse.csr_matrix((d,(r,c)),shape=(len(dict),M.shape[0]))
Run the sum and look at the result (as a dense array):
In [310]: (idx*M).A Out[310]: array([[ 3, 5, 7], [ 9, 12, 15], [ 9, 11, 13], [42, 45, 48]], dtype=int32)
Here is the original for comparison.
In [312]: MA Out[312]: array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11], [12, 13, 14], [15, 16, 17], [18, 19, 20], [21, 22, 23]], dtype=int32)