4

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
  • 1
    x is defined to be of length 3 but you later reference it as having 4 elements. Commented Feb 22, 2021 at 11:51
  • x is arbitrary and only chosen as an example, simple mistake :) Commented Feb 22, 2021 at 11:55
  • 3
    Does this answer your question? Increment Numpy array with repeated indices Commented Feb 22, 2021 at 11:56
  • 2
    That link includes an answer that uses add.at that was provided to get around a buffering issue in +=. Commented Feb 22, 2021 at 12:31

4 Answers 4

3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

my solution not only gets the number of occurrences but also adds them to the given array x. If you want to do the same with bincount then see the linked duplicate question stackoverflow.com/a/2004468/3944322. (I admit that bincount is faster)
it doesnt, your += in your solution is unnecessary, you are just replacing the indexed x array by its corresponding counts. same can be achieved with x[idx] = cnt. The benefit of += is when you are updating the values repeatedly, which you are not. So essentially your answer is exactly the same as mine, which is "replacing the indexes with their frequency counts:"
3

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

Comments

2

You can use unique with return_counts set to True:

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

6 Comments

Technically, this is the same as np.bincount, as i show in my answer. You are replacing the indexes by their frequency counts.
@AkshaySehgal yes, but the question was not to get the number of occurrences of each index but to add 1 to a given array for a list of indices. So in my opinion you answered a different question (maybe OP had this in mind, but at least he didn't pose the question this way)
Actually, even your code doesnt incrementally add anything. The += is unnecessary since you are not repeating the addition. the same result is achieved when you use x[idx] = cnt. so technically, you are also just indexing the array and then replacing it with its count, as np.bincount does.
@AkshaySehgal you need += as OP wrote "x is arbitrary and only chosen as an example".
I dont think thats the case, because OP says their arrays are zeros. but it could be a case as you mention it. in anycase, your answer is a sufficiently good solution to the problem.
|
1

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.