
HI all, I need to do something I thought would be simple -- set all the values of an array to some minimum. so I did this:
min_value = 2 a = np.array((1, 2, 3, 4, 5,)) np.maximum(a, min_value) array([2, 2, 3, 4, 5])
all was well... then I realized that a could have negative numbers in in, and I really wanted the absolute value to be greater than than minimum:
a = np.array((1, 2, 3, 4, -5,)) np.maximum(a, min_value) array([2, 2, 3, 4, 2])
oops! so I added a sign() and abs():
np.sign(a) * np.maximum(np.abs(a), min_value) array([ 2, 2, 3, 4, -5])
all was well. However it turns out a could contain a zero:
a = np.array((0, 1, 2, 3, 4, -5,)) np.sign(a) * np.maximum(np.abs(a), min_value) array([ 0, 2, 2, 3, 4, -5])
Darn! I want that zero to become a 2, but sign(0) = 0, so that doesn't work. How can I do this without another line of code special casing the 0, which isn't that big I deal, but it seems kind of ugly...
a[a==0] = min_value np.sign(a) * np.maximum(np.abs(a), min_value) array([ 2, 2, 2, 3, 4, -5])
thanks, -Chris -- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov

On Fri, Aug 29, 2008 at 2:35 PM, Christopher Barker <Chris.Barker@noaa.gov> wrote:
HI all,
I need to do something I thought would be simple -- set all the values of an array to some minimum. so I did this:
min_value = 2 a = np.array((1, 2, 3, 4, 5,)) np.maximum(a, min_value) array([2, 2, 3, 4, 5])
all was well... then I realized that a could have negative numbers in in, and I really wanted the absolute value to be greater than than minimum:
a = np.array((1, 2, 3, 4, -5,)) np.maximum(a, min_value) array([2, 2, 3, 4, 2])
oops!
so I added a sign() and abs():
np.sign(a) * np.maximum(np.abs(a), min_value) array([ 2, 2, 3, 4, -5])
all was well. However it turns out a could contain a zero:
a = np.array((0, 1, 2, 3, 4, -5,)) np.sign(a) * np.maximum(np.abs(a), min_value) array([ 0, 2, 2, 3, 4, -5])
Darn! I want that zero to become a 2, but sign(0) = 0, so that doesn't work.
How can I do this without another line of code special casing the 0, which isn't that big I deal, but it seems kind of ugly...
a[a==0] = min_value np.sign(a) * np.maximum(np.abs(a), min_value) array([ 2, 2, 2, 3, 4, -5])
Does this work?
x array([ 1., 2., -5., -1., 0.]) np.sign(x) * np.clip(np.absolute(x), 2, np.inf) array([ 2., 2., -5., -2., 0.])

On Fri, Aug 29, 2008 at 2:49 PM, Keith Goodman <kwgoodman@gmail.com> wrote:
On Fri, Aug 29, 2008 at 2:35 PM, Christopher Barker <Chris.Barker@noaa.gov> wrote:
HI all,
I need to do something I thought would be simple -- set all the values of an array to some minimum. so I did this:
min_value = 2 a = np.array((1, 2, 3, 4, 5,)) np.maximum(a, min_value) array([2, 2, 3, 4, 5])
all was well... then I realized that a could have negative numbers in in, and I really wanted the absolute value to be greater than than minimum:
a = np.array((1, 2, 3, 4, -5,)) np.maximum(a, min_value) array([2, 2, 3, 4, 2])
oops!
so I added a sign() and abs():
np.sign(a) * np.maximum(np.abs(a), min_value) array([ 2, 2, 3, 4, -5])
all was well. However it turns out a could contain a zero:
a = np.array((0, 1, 2, 3, 4, -5,)) np.sign(a) * np.maximum(np.abs(a), min_value) array([ 0, 2, 2, 3, 4, -5])
Darn! I want that zero to become a 2, but sign(0) = 0, so that doesn't work.
How can I do this without another line of code special casing the 0, which isn't that big I deal, but it seems kind of ugly...
a[a==0] = min_value np.sign(a) * np.maximum(np.abs(a), min_value) array([ 2, 2, 2, 3, 4, -5])
Does this work?
x array([ 1., 2., -5., -1., 0.]) np.sign(x) * np.clip(np.absolute(x), 2, np.inf) array([ 2., 2., -5., -2., 0.])
Oh, I guess 0 is less than 2.

On Fri, Aug 29, 2008 at 2:52 PM, Keith Goodman <kwgoodman@gmail.com> wrote:
On Fri, Aug 29, 2008 at 2:49 PM, Keith Goodman <kwgoodman@gmail.com> wrote:
On Fri, Aug 29, 2008 at 2:35 PM, Christopher Barker <Chris.Barker@noaa.gov> wrote:
HI all,
I need to do something I thought would be simple -- set all the values of an array to some minimum. so I did this:
min_value = 2 a = np.array((1, 2, 3, 4, 5,)) np.maximum(a, min_value) array([2, 2, 3, 4, 5])
all was well... then I realized that a could have negative numbers in in, and I really wanted the absolute value to be greater than than minimum:
a = np.array((1, 2, 3, 4, -5,)) np.maximum(a, min_value) array([2, 2, 3, 4, 2])
oops!
so I added a sign() and abs():
np.sign(a) * np.maximum(np.abs(a), min_value) array([ 2, 2, 3, 4, -5])
all was well. However it turns out a could contain a zero:
a = np.array((0, 1, 2, 3, 4, -5,)) np.sign(a) * np.maximum(np.abs(a), min_value) array([ 0, 2, 2, 3, 4, -5])
Darn! I want that zero to become a 2, but sign(0) = 0, so that doesn't work.
How can I do this without another line of code special casing the 0, which isn't that big I deal, but it seems kind of ugly...
a[a==0] = min_value np.sign(a) * np.maximum(np.abs(a), min_value) array([ 2, 2, 2, 3, 4, -5])
Does this work?
x array([ 1., 2., -5., -1., 0.]) np.sign(x) * np.clip(np.absolute(x), 2, np.inf) array([ 2., 2., -5., -2., 0.])
Oh, I guess 0 is less than 2.
If you only have integers then
x array([ 1, 2, -5, -1, 0]) np.sign(x+1e-16) * np.maximum(np.abs(x), 2) array([ 2., 2., -5., -2., 2.])

Alan G Isaac wrote:
Does this do what you want? idx = np.abs(a)<min_value a[idx] = min_value
yup, that's it. I had forgotten about that kind of indexing, even though I used it for: a[a==0] = min_value Keith Goodman wrote:
If you only have integers then
x array([ 1, 2, -5, -1, 0]) np.sign(x+1e-16) * np.maximum(np.abs(x), 2) array([ 2., 2., -5., -2., 2.])
that would work, though I like Alan's better. thanks, -Chris -- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov

On Fri, Aug 29, 2008 at 3:08 PM, Christopher Barker <Chris.Barker@noaa.gov> wrote:
Alan G Isaac wrote:
Does this do what you want? idx = np.abs(a)<min_value a[idx] = min_value
yup, that's it. I had forgotten about that kind of indexing, even though I used it for: a[a==0] = min_value
Keith Goodman wrote:
If you only have integers then
x array([ 1, 2, -5, -1, 0]) np.sign(x+1e-16) * np.maximum(np.abs(x), 2) array([ 2., 2., -5., -2., 2.])
that would work, though I like Alan's better.
I thought -1 should go to -2. If not, then my attempt doesn't work.

Keith Goodman wrote:
Alan G Isaac wrote:
Does this do what you want? idx = np.abs(a)<min_value a[idx] = min_value
If you only have integers then
x array([ 1, 2, -5, -1, 0]) np.sign(x+1e-16) * np.maximum(np.abs(x), 2) array([ 2., 2., -5., -2., 2.])
Keith Goodman wrote: that would work, though I like Alan's better.
I thought -1 should go to -2. If not, then my attempt doesn't work.
arrg! yes, you are quite right -- -1 should go to -2. That's what I get for trying to get home early before the holiday weekend.... honestly, in this case, it probably doesn't matter much. I'm using this in my wxPython data-visualization oriented 2-d drawing library: FloatCanvas. When you zoom out an a rectangle, at some point it gets very small and disappears. Often that is appropriate. however, in some users, folks want it to reach a minimum size, say a few pixels, and not get smaller. The trick is that rectangles can have a height that is negative due to swapping the y axis to be y-up, rather than y-down, like it usually is for graphics drawing. So if the user wants a minimum height of 2, and the rect has a height of -1 after scaling, it should really get a height of -2. as we're only talking a couple pixels, it probably doesn't matter, and that's why I didn't notice the error. thanks, -Chris -- Christopher Barker, Ph.D. Oceanographer NOAA/OR&R/HAZMAT (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception

Alan G Isaac wrote:
Alan G Isaac wrote:
Does this do what you want? idx = np.abs(a)<min_value a[idx] = min_value
Christopher Barker wrote:
-1 should go to -2
ok then: a[idx] = min_value*np.sign(a[idx]) I think that's what you are saying?
nope:
a = np.array((0, 1, -1, 2, 3, -5,)) idx = np.abs(a)<min_value a = np.array((0, 1, -1, 2, 3, -5,)) a array([ 0, 1, -1, 2, 3, -5])
0 should go to 2 --it's not, because sign(0) == 0, so the 2 gets turned to zero, my original problem. Frankly, as I've only seen sign() used for this sort of thing, it makes me think that sign(0) really should be 1 -- the identity -- I know that 0 is neither positive nor negative, but as it is often used in this way, it would be more useful for sign(0) to be the identity. I'm not advocating a change in numpy, I'm sure this is established standard, but it does seem I need to special case zero. (Or fudge it by adding an epsilon, as Keith suggested. thanks all, -Chris -- Christopher Barker, Ph.D. Oceanographer NOAA/OR&R/HAZMAT (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception

Alan G Isaac wrote:
Does this do what you want? idx = np.abs(a)<min_value a[idx] = min_value
out of interest, is there any performance difference between: a[np.abs(a)<min_value] = min_value and: a = np.where(np.abs(a)<min_value, min_value, a) I think the former is more readable. -Chris -- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov

2008/8/29 Christopher Barker <Chris.Barker@noaa.gov>:
How can I do this without another line of code special casing the 0, which isn't that big I deal, but it seems kind of ugly...
a[a==0] = min_value np.sign(a) * np.maximum(np.abs(a), min_value) array([ 2, 2, 2, 3, 4, -5])
Maybe (np.sign(a) | 1) * np.maximum(np.abs(a), min_value) is a little bit easier on the eye. Cheers Stéfan

On Sat, Aug 30, 2008 at 6:24 AM, Alan G Isaac <aisaac@american.edu> wrote:
Stéfan van der Walt wrote:
(np.sign(a) | 1) ...
Ah, that's nice. How about idx = np.abs(a)<min_value a[idx] = min_value*(np.sign(a[idx]) | 1)
Or, since he asked to do it in one line,
min_value = 2 x array([ 1, 2, -5, -1, 0]) np.sign(x | 1) * np.maximum(np.abs(x), min_value) array([ 2, 2, -5, -2, 2])

On Sat, Aug 30, 2008 at 7:29 AM, Keith Goodman <kwgoodman@gmail.com> wrote:
On Sat, Aug 30, 2008 at 6:24 AM, Alan G Isaac <aisaac@american.edu> wrote:
Stéfan van der Walt wrote:
(np.sign(a) | 1) ...
Ah, that's nice. How about idx = np.abs(a)<min_value a[idx] = min_value*(np.sign(a[idx]) | 1)
Or, since he asked to do it in one line,
min_value = 2 x array([ 1, 2, -5, -1, 0]) np.sign(x | 1) * np.maximum(np.abs(x), min_value) array([ 2, 2, -5, -2, 2])
Why did I send that? Sorry. I saw Stéfan's (np.sign(a) | 1), plugged it in and sent it. But Stéfan already did that. An automated 5 minute delay on sending numpy email would cut the email you get from me in half.

Stéfan van der Walt wrote:
Maybe
(np.sign(a) | 1) * np.maximum(np.abs(a), min_value)
is a little bit easier on the eye.
nice! that does it. somehow I never think of using or. Alan G Isaac wrote:
idx = np.abs(a)<min_value a[idx] = min_value*(np.sign(a[idx]) + (a[idx]==0))
that's do it too, but it's a bit more wordy, and I'm guessing slower, though that's really irrelevant here. thanks all, -Chris -- Christopher Barker, Ph.D. Oceanographer NOAA/OR&R/HAZMAT (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception
participants (4)
-
Alan G Isaac
-
Christopher Barker
-
Keith Goodman
-
Stéfan van der Walt