问题
I have a numpy array A and I want to modify values in it using a indexing list B. But the thing is in my slicing I can have an element of the array multiple times... This example will explain better what I mean by that :
import numpy as np
A = np.arange(5) + 0.5
B = np.array([0, 1, 0, 2, 0, 3, 0, 4])
print A[B]
returns as expected [ 0.5 1.5 0.5 2.5 0.5 3.5 0.5 4.5].
However if I do that :
A[B] += 1.
print A
I was expecting to obtain [ 4.5 2.5 3.5 4.5 5.5] as the first element is repeated 4 times in the indexing vector B, but it returns [ 1.5 2.5 3.5 4.5 5.5].
So how can I do what I actually wanted to do? (without using any loop as I'm using that on very large arrays)
回答1:
The explanation why this happens is a little involved, but basically, "buffering ate your homework." There are a couple of ways around this issue of numpy ufuncs. The proper one, that will work with any operation is to use the corresponding ufunc's at method:
>>> A = np.arange(5) + 0.5
>>> B = np.array([0, 1, 0, 2, 0, 3, 0, 4])
>>> np.add.at(A, B, 1)
>>> A
array([ 4.5, 2.5, 3.5, 4.5, 5.5])
This tends to be kind of slow, so for the fastest performance possible, and only for addition, you can use np.bincount:
>>> A = np.arange(5) + 0.5
>>> A += np.bincount(B) * 1 # replace the 1 with the number you want to add
>>> A
array([ 4.5, 2.5, 3.5, 4.5, 5.5])
EDIT
If what you want to add is an array of the same length as B, then the following, using bincount, is probably going to run faster than the first method:
>>> A = np.arange(5) + 0.5
>>> C = np.ones_like(B) # They are all ones, but could be anything
>>> A += np.bincount(B, weights=C)
>>> A
array([ 4.5, 2.5, 3.5, 4.5, 5.5])
来源:https://stackoverflow.com/questions/28205449/indexing-slicing-in-numpy-array-to-modify-it