1

I was trying to vectorize some list calculation, but find something weird when I attempting to use list as index, especially when I try to write back to the original list, repeated list index seems to be useless:

import numpy as np

x = np.arange(10)
y = np.array([1,2,3,4,5])
z = np.array([1,1,1,1,1])

print(x[y], x[z])

>>out: [1 2 3 4 5] [1 1 1 1 1], same as I expected

x = np.arange(10)
x[y] -= 1
print(x[y])

>>out: [0 1 2 3 4] this is good as no repeating in index list

x = np.arange(10)
x[z] -= 1
print(x[y])

>> out:[0 2 3 4 5], Here I am expecting [-4 2 3 4 5], which means x[1] should -- for 5 times, but it turns out to subtract only once

Sock Xu
  • 11
  • 1
  • 1
    Perhaps a duplicate of this?: https://stackoverflow.com/questions/15973827/handling-of-duplicate-indices-in-numpy-assignments – Jeppe Feb 16 '19 at 22:35

1 Answers1

2

There's a buffering issue. ufuncs were given a .at method to resolve this:

In [392]: np.add.at(x,z,-1)
In [394]: x[y]
Out[394]: array([-4,  2,  3,  4,  5])

I think the documentation for ufunc.at explains this well

https://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.at.html

It's come up periodically in other SO questions.

x[z] -= 1

is evaluated like:

x[z] = x[z] -1

while you were expecting:

for i in z:
    x[i] -= 1
hpaulj
  • 221,503
  • 14
  • 230
  • 353