Re: [Numpy-discussion] Numpy unexpected (for me) behaviour

At 01:44 23/01/2009 -0600, Robert Kern wrote:
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.
Well inevitable would not be the word I would use. I would have expected a different behaviour between a[b] = a[b] + 1 and a[b] += 1 In the second case python (or numpy) does not need to generate an intermediate array and could be doing in-place operations.
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.
Indeed what I am doing is very close to histogramming. Unfortunaly what I have to add is not just one but a value. I have a set of scattered points (x,y,z) and values corresponding to those points. My goal is to get a regular grid in which in each voxel I sum the values of the points falling in them. I guess I will have to write a tiny C extension. I had expected the += sintax would trigger the in-place operation. Best regards, Armando

On Fri, Jan 23, 2009 at 02:10, V. Armando Sole <sole@esrf.fr> wrote:
At 01:44 23/01/2009 -0600, Robert Kern wrote:
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.
Well inevitable would not be the word I would use. I would have expected a different behaviour between a[b] = a[b] + 1 and a[b] += 1
In the second case python (or numpy) does not need to generate an intermediate array and could be doing in-place operations.
I'm sorry, but that is how Python implements a[b] += 1. We have no control over it. There is simply no hook to implement that statement as an atomic unit. Instead, we have three hooks, __getitem__, __setitem__, and __iadd__. __iadd__ is orthogonal to the former two, so it can't know that it is operating in that context.
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.
Indeed what I am doing is very close to histogramming.
Unfortunaly what I have to add is not just one but a value. I have a set of scattered points (x,y,z) and values corresponding to those points. My goal is to get a regular grid in which in each voxel I sum the values of the points falling in them.
That's what the weights input is for.
I guess I will have to write a tiny C extension. I had expected the += sintax would trigger the in-place operation.
It does, just a different one than you want. -- 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 (2)
-
Robert Kern
-
V. Armando Sole