1

I have a function that works perfectly. It takes a numpy 2D array and do something by the array then returns it back. I try to use the returned value to fill an array by a condition. look at below code:

>>> import numpy as np
>>> x=np.random.randint(20, size=(4,5))
>>> y=np.zeros_like(x) * np.nan
>>> x
array([[19,  0,  6, 17,  5],
       [18, 18, 10, 19,  9],
       [ 2,  5, 10,  5, 15],
       [ 9,  3,  0,  6,  9]])
>>> y
array([[ nan,  nan,  nan,  nan,  nan],
       [ nan,  nan,  nan,  nan,  nan],
       [ nan,  nan,  nan,  nan,  nan],
       [ nan,  nan,  nan,  nan,  nan]])
>>> y[ x>15 ] = 1000
>>> y
array([[ 1000.,    nan,    nan,  1000.,    nan],
       [ 1000.,  1000.,    nan,  1000.,    nan],
       [   nan,    nan,    nan,    nan,    nan],
       [   nan,    nan,    nan,    nan,    nan]])

problem is when add a function like.

>>> def foo(x):
    return x*2

>>> y[ x>15 ] = foo(x)

Warning (from warnings module):
  File "__main__", line 1
FutureWarning: assignment exception type will change in the future
Traceback (most recent call last):
  File "<pyshell#59>", line 1, in <module>
    y[ x>15 ] = foo(x)
ValueError: boolean index array should have 1 dimension

or something like:

>>> _=foo(x)
>>> y[ x>15 ]=_
Traceback (most recent call last):
  File "<pyshell#64>", line 1, in <module>
    y[ x>15 ]=_
ValueError: boolean index array should have 1 dimension

why it does not work any more!?

6
  • Why you want a matrix of nan instead of 0s? Commented Aug 2, 2017 at 9:32
  • 2
    In your first try you use a scalar. In the second one you have a 2D array. Their sizes don't match. You can use np.where(x>15, foo(x), y). Commented Aug 2, 2017 at 9:32
  • @IgnacioVergaraKausel I have some conditions. in one of them y must be 0 and in other y must be 1 else y must be nan. I need nan's. Commented Aug 2, 2017 at 9:37
  • @ayhan yes thats right, or reshape the result ? instead using of where Commented Aug 2, 2017 at 9:38
  • 1
    @pdshah Yes, maybe y[x>15] = foo(x[x>15]) Commented Aug 2, 2017 at 9:40

1 Answer 1

1

Your major problem is that a boolean-indexed array returns a 1d array, so:

y[x > 15]
[Out]: array([nan, nan, nan, nan, nan])

So if you want to assign to it you need a 1-d array of the same size (or something that broadcasts to 1d, like a 0d scalar as you did in your first example).

So either boolean slice your input

y[x > 15] = foo(x[x > 15])  # or
y[x > 15] = foo(x)[x > 15]

Or use np.where, which preserves the shape.

y = np.where(x > 15, foo(x), y)

The first option is faster, but np.where is generally more clear and extensible.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.