Folks, I'm running into the following problem with putmask on take.
import numpy x = N.arange(12.) m = [1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1] i = N.nonzero(m)[0] w = N.array([-1, -2, -3, -4.]) x.putmask(w,m) x.take(i) N.allclose(x.take(i),w) False
I'm wondering ifit is intentional, or if it's a problem on my build (1.0b5), or if somebody experienced it as well. Thanks a lot for your input. P.
Hi P., On Thu, Sep 21, 2006 at 07:40:39PM -0400, PGM wrote:
I'm running into the following problem with putmask on take.
import numpy x = N.arange(12.) m = [1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1] i = N.nonzero(m)[0] w = N.array([-1, -2, -3, -4.]) x.putmask(w,m) x.take(i) N.allclose(x.take(i),w)
According to the putmask docstring: a.putmask(values, mask) sets a.flat[n] = v[n] for each n where mask.flat[n] is true. v can be scalar. This would mean that 'w' is not of the right length. Would the following do what you want? import numpy as N m = N.array([1,0,0,0,0,0,1,0,0,1,0,1],dtype=bool) w = N.array([-1,-2,-3,-4]) x[m] = w Regards Stéfan
Stefan van der Walt wrote:
Hi P.,
On Thu, Sep 21, 2006 at 07:40:39PM -0400, PGM wrote:
I'm running into the following problem with putmask on take.
import numpy x = N.arange(12.) m = [1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1] i = N.nonzero(m)[0] w = N.array([-1, -2, -3, -4.]) x.putmask(w,m) x.take(i) N.allclose(x.take(i),w)
According to the putmask docstring:
a.putmask(values, mask) sets a.flat[n] = v[n] for each n where mask.flat[n] is true. v can be scalar.
This would mean that 'w' is not of the right length.
There are 4 true values in m and 4 values in w. What's the wrong length? For the sake of clarity: In [1]: from numpy import * In [3]: m = [1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1] In [4]: i = nonzero(m)[0] In [5]: i Out[5]: array([ 0, 6, 9, 11]) In [6]: w = array([-1, -2, -3, -4.]) In [7]: x = arange(12.) In [8]: x.putmask(w, m) In [9]: x Out[9]: array([ -1., 1., 2., 3., 4., 5., -3., 7., 8., -2., 10., -4.]) In [17]: x[array(m, dtype=bool)] = w In [18]: x Out[18]: array([ -1., 1., 2., 3., 4., 5., -2., 7., 8., -3., 10., -4.]) Out[9] and Out[18] should have been the same, but elements 6 and 9 are flipped. It's pretty clear that this is a bug in .putmask(). -- 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, Sep 22, 2006 at 02:17:57AM -0500, Robert Kern wrote:
Stefan van der Walt wrote:
Hi P.,
On Thu, Sep 21, 2006 at 07:40:39PM -0400, PGM wrote:
I'm running into the following problem with putmask on take.
import numpy x = N.arange(12.) m = [1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1] i = N.nonzero(m)[0] w = N.array([-1, -2, -3, -4.]) x.putmask(w,m) x.take(i) N.allclose(x.take(i),w)
According to the putmask docstring:
a.putmask(values, mask) sets a.flat[n] = v[n] for each n where mask.flat[n] is true. v can be scalar.
This would mean that 'w' is not of the right length.
There are 4 true values in m and 4 values in w. What's the wrong length?
The way I read the docstring, you use putmask like this: In [4]: x = N.array([1,2,3,4]) In [5]: x.putmask([4,3,2,1],[1,0,0,1]) In [6]: x Out[6]: array([4, 2, 3, 1])
For the sake of clarity:
In [1]: from numpy import *
In [3]: m = [1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1]
In [4]: i = nonzero(m)[0]
In [5]: i Out[5]: array([ 0, 6, 9, 11])
In [6]: w = array([-1, -2, -3, -4.])
In [7]: x = arange(12.)
In [8]: x.putmask(w, m)
In [9]: x Out[9]: array([ -1., 1., 2., 3., 4., 5., -3., 7., 8., -2., 10., -4.])
In [17]: x[array(m, dtype=bool)] = w
In [18]: x Out[18]: array([ -1., 1., 2., 3., 4., 5., -2., 7., 8., -3., 10., -4.])
Out[9] and Out[18] should have been the same, but elements 6 and 9 are flipped. It's pretty clear that this is a bug in .putmask().
Based purely on what I read in the docstring, I would expect the above to do x[0] = w[0] x[6] = w[6] x[9] = w[9] x[11] = w[11] Since w is of length 4, you'll probably get indices modulo 4: w[6] == w[2] == -3 w[9] == w[1] == -2 w[11] == w[3] == -4 Which seems to explain what you are seeing. Regards Stéfan
Stefan van der Walt wrote:
On Fri, Sep 22, 2006 at 02:17:57AM -0500, Robert Kern wrote:
According to the putmask docstring:
a.putmask(values, mask) sets a.flat[n] = v[n] for each n where mask.flat[n] is true. v can be scalar.
This would mean that 'w' is not of the right length.
There are 4 true values in m and 4 values in w. What's the wrong
length?
The way I read the docstring, you use putmask like this:
In [4]: x = N.array([1,2,3,4])
In [5]: x.putmask([4,3,2,1],[1,0,0,1])
In [6]: x Out[6]: array([4, 2, 3, 1])
Out[9] and Out[18] should have been the same, but elements 6 and 9 are flipped. It's pretty clear that this is a bug in .putmask().
Based purely on what I read in the docstring, I would expect the above to do
x[0] = w[0] x[6] = w[6] x[9] = w[9] x[11] = w[11]
Since w is of length 4, you'll probably get indices modulo 4:
w[6] == w[2] == -3 w[9] == w[1] == -2 w[11] == w[3] == -4
Which seems to explain what you are seeing.
Yes, this does explain what you are seeing. It is the behavior of Numeric's putmask (where this method came from). It does seem counter-intuitive, and I'm not sure what to do with it. In some sense putmask should behave the same as x[m] = w. But, on the other-hand, was anybody actually using the "modular" indexing "feature" of "putmask". Here are our options: 1) "fix-it" and risk breaking code for people who used putmask and the modular indexing "feature," 2) Get rid of it as a method (and keep it as a function so that oldnumeric can use it.) 3) Keep everything the way it is. -Travis
Travis Oliphant wrote:
Yes, this does explain what you are seeing. It is the behavior of Numeric's putmask (where this method came from). It does seem counter-intuitive, and I'm not sure what to do with it. In some sense putmask should behave the same as x[m] = w. But, on the other-hand, was anybody actually using the "modular" indexing "feature" of "putmask".
Here are our options:
1) "fix-it" and risk breaking code for people who used putmask and the modular indexing "feature," 2) Get rid of it as a method (and keep it as a function so that oldnumeric can use it.) 3) Keep everything the way it is.
O.K. putmask is keeping the same behavior (it is intentional behavior and has been for a long time). However, because of the confusion, it is being removed as a method (I know this is late, but it's a little-used method and was only added by NumPy). Putmask will be a function. Also, the remaining put method will have it's arguments switched to match the function. IIRC the original switch was made to accomodate masked arrays methods of the same name. But, this does not really help anyway since arr.put for a masked array doesn't even take an indicies argument, so confusing users who don't even use masked arrays seems pointless. Scream now if you think I'm being unreasonable. This will be in 1.0rc2 (yes we will need rc2) The original poster has still not explained why a[mask] = values does not work suitably. -Travis
participants (5)
-
PGM
-
Robert Kern
-
Stefan van der Walt
-
Travis Oliphant
-
Travis Oliphant