Add 1 to numpy array from a list of indices?

Viewed 1155

I have a numpy array-like

x = np.zeros(4, dtype=np.int)

And I have a list of indices like [1, 2, 3, 2, 1] and I want to add 1 to the corresponding array elements, such that for each element in the index list, x is incremented at that position:

x = [0, 2, 2, 1]

I tried doing this using:

x[indices] += 1

But for some reason, it only updates the indices once, and if an index occurs more often than once it is not registered. I could of course just create a simple for loop but I was wondering if there is a one-line solution.

4 Answers

What you are essentially trying to do, is to replace the indexes by their frequencies.

Try np.bincount. Technically that does the same what you are trying to do.

indices = [1, 2, 3, 2, 1]

np.bincount(indices)
array([0, 2, 2, 1])

If you think about what you are doing. You are saying that for index 0, you dont want to count anything. but for index 1, you want 2 counts, .. and so on. Hope that gives you an intuitive sense of why this is the same.

@Stef's solution with np.unique, does exactly the same thing as what np.bincount would do.

You can use unique with return_counts set to True:

idx, cnt = np.unique(indices, return_counts=True)
x[idx] += cnt

You want np.add.at:

np.add.at(x, indices, 1)
x
Out[]:
array([0, 2, 2, 1])

This works even if x doesn't start out as np.zeros

Based on your question, you can really just write

import numpy as np 
indices = [1, 2, 3, 2, 1]
x = np.array([indices.count(i) for i in range(4)])

Because count counts repeated elements. But the full solution would be

import numpy as np 
x = np.zeros(4, dtype=np.int)
indices = [1, 2, 3, 2, 1]
result = np.array([indices.count(i) for i in range(4)])
x += result
Related