0

So lets say I've got a variable a which is a numpy array. When a is less than a certain value I want to apply a certain function, and when it is greater than this value I would apply a different function.

I've tried doing this with a boolean if statement but return the following error:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

I know from this answer that I need to use numpy a.any() and a.all() but I'm unclear how/where I would use them in the loop. I've provided a really simple example below:

import numpy as np

a = np.linspace(1, 10, num=9)

def sortfoo(a):
    if a < 5:
        b = a*3
    else:
        b = a/2
    return b

result = sortfoo(a)
print(result)

So I guess I'm asking for an example of where and how I need to use any() and all() to the above.

Really basic question but for some reason my brain isn't working clearly. Any help much appreciated.

8556732
  • 281
  • 2
  • 9
  • 2
    Your problem is that you are applying boolean logic `if` to the statement `a<5`. If you try `a<5` by itself, you'll realize it gives you an array of boolean values where `<5` was evaluated against each element in `a` – ASaunders Jun 19 '19 at 17:58

2 Answers2

3

Given the description, this looks like a use case for np.where()

a = np.linspace(1, 10, num=9)

b = np.where(a<5,a*3,a/2)

b
array([ 3.    ,  6.375 ,  9.75  , 13.125 ,  2.75  ,  3.3125,  3.875 ,
    4.4375,  5.    ])

Since you also mention wanting to apply different functions, you can use the same syntax

def f1(n):
    return n*3

def f2(n):
    return n/2

np.where(a<5,f1(a),f2(a))

array([ 3.    ,  6.375 ,  9.75  , 13.125 ,  2.75  ,  3.3125,  3.875 ,
        4.4375,  5.    ])
G. Anderson
  • 5,815
  • 2
  • 14
  • 21
  • 2
    I love the `np.where` … it's clean :) – B.Gees Jun 19 '19 at 19:06
  • This is great, thankyou! Apologies for the late reply – 8556732 Jun 20 '19 at 08:21
  • 1
    This is a fab solution - my actual problem is a lot more complex than this and np.where() works perfectly with many functions. I posted a simple problem, but I can see how this can do way more complex stuff! – 8556732 Jun 20 '19 at 08:30
  • Happy to help! You can also chain multiple conditions into if:elif:elif:else if you require, though there may be better ways depending on your specific problem; `np.where(a<5,f1(a),np.where(a==5,f2(a),a)` – G. Anderson Jun 20 '19 at 15:01
2

Using simple statement in numpy, you can do that:

import numpy as np
a = np.linspace(1, 10, num=9)
s = a < 5 # Test a < 5
a[s] = a[s] * 3
a[s == False] = a[s == False] / 2
B.Gees
  • 1,125
  • 2
  • 11
  • 28
  • 2
    I think you should use np.copy to duplicate the array and make changes to the duplicated array. With the code above, you alter the array in the first line `a[a < 5] = a[a < 5] * 3`, likely causing unwanted changes when evaluating `a > 5` – ASaunders Jun 19 '19 at 18:07
  • One minor issue I see is that you handle `a==5` differently than the OP, should be `>=5` instead of `>5`? – G. Anderson Jun 19 '19 at 18:30
  • Thanks for the answer, sorry my reply is late! Thanks – 8556732 Jun 20 '19 at 08:21
  • @8556732, No problems :) – B.Gees Jun 21 '19 at 00:17