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

Robert Kern robert.kern@gmail....
Fri Jan 23 01:44:14 CST 2009

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

    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

More information about the Numpy-discussion mailing list