问题
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