Raftel
Raftel

Reputation: 161

Why applying a conditional expression doesn't work on numpy array

I can't figure out why my relu function doesn't work but squarer works, how is it different?

import numpy as np

x = np.array([1, 2, 3, 4, 5])

squarer = lambda x: x ** 2
squarer(x)
# array([ 1,  4,  9, 16, 25])

relu = lambda x : 0 if x <= 0 else x
relu(x)
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Upvotes: 0

Views: 313

Answers (1)

hpaulj
hpaulj

Reputation: 231510

In [6]: x = np.array([1, 2, 3, 4, 5])
   ...: 
   ...: squarer = lambda x: x ** 2
   ...: squarer(x)
Out[6]: array([ 1,  4,  9, 16, 25])

The lambda is just a function definition, and is equivalent of doing:

In [7]: x**2
Out[7]: array([ 1,  4,  9, 16, 25])

The function layer doesn't add any iteration. It's the power method of the x array that's doing the elementwise iteration.

In [8]: relu = lambda x : 0 if x <= 0 else x

Similarly the relu does not add any iteration; it's scalar python if/else clause.

In [13]: x = np.arange(-3,4)
In [14]: x
Out[14]: array([-3, -2, -1,  0,  1,  2,  3])

It can be applied to elements of x with a list comprehension:

In [15]: [relu(i) for i in x]
Out[15]: [0, 0, 0, 0, 1, 2, 3]

Arrays have a lt method, so:

In [16]: x<=0
Out[16]: array([ True,  True,  True,  True, False, False, False])

It can be use in masked way:

In [17]: x1=x.copy()
In [18]: x1[x<=0] = 0
In [19]: x
Out[19]: array([-3, -2, -1,  0,  1,  2,  3])
In [20]: x1
Out[20]: array([0, 0, 0, 0, 1, 2, 3])

Or via a where:

In [22]: np.where(x<=0, 0,x)
Out[22]: array([0, 0, 0, 0, 1, 2, 3])

where isn't an iterator either. It is effectively the same thing as the [17][18] lines.

Using an array in a if expression amounts to trying to convert it to a scalar boolean:

In [24]: if x<=0:x
Traceback (most recent call last):
  File "<ipython-input-24-6cecebf070dc>", line 1, in <module>
    if x<=0:x
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

In [25]: bool(x<=0)
Traceback (most recent call last):
  File "<ipython-input-25-f1a519ed746f>", line 1, in <module>
    bool(x<=0)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

It works it the array has only one element, but otherwise it raises this ambiguity error:

In [26]: bool(np.array(1)<=0)
Out[26]: False

but for "empty" array:

In [28]: bool(np.array([])<=0)
<ipython-input-28-03e1626841fc>:1: DeprecationWarning: The truth value of an empty array is ambiguous. Returning False, but in future this will result in an error. Use `array.size > 0` to check that an array is not empty.
  bool(np.array([])<=0)
Out[28]: False

But testing for a 'empty' list is ok:

In [29]: bool([])
Out[29]: False

Upvotes: 1

Related Questions