Search code examples
numpyarray-broadcastingnumpy-slicing

How do I sparsely add the rows of a numpy array to another numpy array?


I have a large 2D array (A) and a smaller 2D array of the same number of columns but fewer number of rows (B). I want to add the rows of my smaller array to rows of my larger array, but there are rows in between that I don't want to affect. I have an index array that details the rows I want to add to, like this:

A = np.array([[0, 0, 0, 0],
              [0, 0, 0, 0],
              [0, 0, 0, 0],
              [0, 0, 0, 0],
              [0, 0, 0, 0],
              [0, 0, 0, 0],
              [0, 0, 0, 0]])
B = np.array([[1, 3, 2, 4],
              [6, 2, 5, 1],
              [2, 8, 1, 4]])
Index = np.array([1, 4, 5])
Result = np.array([[0, 0, 0, 0],
                   [1, 3, 2, 4],
                   [0, 0, 0, 0],
                   [0, 0, 0, 0],
                   [6, 2, 5, 1],
                   [2, 8, 1, 4],
                   [0, 0, 0, 0]])

My real arrays do not have any sort of pattern to the rows that can be sliced on, and my large array A will not necessarily be a bunch of zeros, so I do actually need to add them.

I thought that np.apply_along_axis would be useful, but there are two things about using it that I can't figure out. One is that my indexes are not clustered together, and I don't know how to tell apply_along_axis to 'skip' a slice. Two is that I'm only traversing though my large array A with take_along_axis, so I don't know how, within my provided function, to tell it which row of array B it should be adding. Can I do this or is there another way?


Solution

  • Use np.add.at().

    np.add.at(A, Index, B)
    

    Alternatively, you could do this:

    A[Index] += B
    

    (Note: this will not work if Index contains duplicates.)