I want to find a fast way (without for loop) in Python to assign reoccuring indices of an array. This is the desired result using a for loop:
import numpy as np
a=np.arange(9, dtype=np.float64).reshape((3,3))
# The array indices: [2,3,4] are identical.
Px = np.uint64(np.array([0,1,1,1,2]))
Py = np.uint64(np.array([0,0,0,0,0]))
# The array to be added at the array indices (may also contain random numbers).
x = np.array([.1,.1,.1,.1,.1])
for m in np.arange(len(x)):
a[Px[m]][Py[m]] += x
print a
%[[ 0.1 1. 2.]
%[ 3.3 4. 5.]
%[ 6.1 7. 8.]]
When I try to add x
to a
at the indices Px,Py
I obviously do not get the same result (3.3 vs. 3.1):
a[Px,Py] += x
print a
%[[ 0.1 1. 2.]
%[ 3.1 4. 5.]
%[ 6.1 7. 8.]]
Is there a way to do this with numpy? Thanks.
Yes, it can be done, but it is a little tricky:
# convert yourmulti-dim indices to flat indices
flat_idx = np.ravel_multi_index((Px, Py), dims=a.shape)
# extract the unique indices and their position
unique_idx, idx_idx = np.unique(flat_idx, return_inverse=True)
# Aggregate the repeated indices
deltas = np.bincount(idx_idx, weights=x)
# Sum them to your array
a.flat[unique_idx] += deltas