Numpy unexpected (for me) behaviour
Hello, In an effort to suppress for loops, I have arrived to the following situation. Through vectorial logical operations I generate a set of indices for which the contents of an array have to be incremented. My problem can be reduced to the following: #This works import numpy a=numpy.zeros(10) b=numpy.ones(4, numpy.int) for i in b: a[i] += 1 #a[1] contains 4 at the end #This does not work import numpy a=numpy.zeros(10) b=numpy.ones(4, numpy.int) a[b] += 1 #a[1] contains 1 at the end Is that a bug or a feature? Is there a way I can achieve the first result without a for loop? In my application the difference is a factor 10 in execution time (1000 secons instead of 100 ...) Thanks, Armando
On Fri, Jan 23, 2009 at 01:39, Matthew Brett <matthew.brett@gmail.com> wrote:
Hi,
#This does not work import numpy a=numpy.zeros(10) b=numpy.ones(4, numpy.int) a[b] += 1
The problem here is that you are setting a[1] to a[1]+1.
I think you want:
import numpy a=numpy.zeros(10) b=numpy.ones(4, numpy.bool) a[b] += 1
Judging from his for loop, he does want the integer array. He's doing something like histogramming. -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco
On Fri, Jan 23, 2009 at 01:11, V. Armando Sole <sole@esrf.fr> wrote:
Hello,
In an effort to suppress for loops, I have arrived to the following situation.
Through vectorial logical operations I generate a set of indices for which the contents of an array have to be incremented. My problem can be reduced to the following:
#This works import numpy a=numpy.zeros(10) b=numpy.ones(4, numpy.int)
for i in b: a[i] += 1 #a[1] contains 4 at the end
#This does not work import numpy a=numpy.zeros(10) b=numpy.ones(4, numpy.int) a[b] += 1
#a[1] contains 1 at the end
Is that a bug or a feature?
It is an inevitable consequence of several features interacting together. Basically, Python expands "a[b] += 1" into this: c = a[b] d = c.__iadd__(1) a[b] = d Basically, the array c doesn't know that it was created by indexing a, so it can't do the accumulation you want.
Is there a way I can achieve the first result without a for loop? In my application the difference is a factor 10 in execution time (1000 secons instead of 100 ...)
In [6]: bincount? Type: builtin_function_or_method Base Class: <type 'builtin_function_or_method'> String Form: <built-in function bincount> Namespace: Interactive Docstring: bincount(x,weights=None) Return the number of occurrences of each value in x. x must be a list of non-negative integers. The output, b[i], represents the number of times that i is found in x. If weights is specified, every occurrence of i at a position p contributes weights[p] instead of 1. See also: histogram, digitize, unique. -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco
participants (3)
-
Matthew Brett
-
Robert Kern
-
V. Armando Sole