【问题标题】:Why applying a conditional expression doesn't work on numpy array为什么应用条件表达式不适用于 numpy 数组
【发布时间】:2021-08-09 19:53:29
【问题描述】:

我不明白为什么我的relu 函数不起作用但squarer 起作用,它有什么不同?

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()

【问题讨论】:

  • x &lt;= 0的价值你有什么不明白的?
  • “squarer”起作用的原因是 ** 运算符自动映射到它的 LHS(可能是 RHS,两个)。 "0 if x..." 表达式没有,因此 x 被视为一个数组,您会得到错误。
  • 要以矢量化形式编写if 测试,您可以使用np.where: relu = lambda x : np.where(x &lt;= 0, 0, x)
  • @hpaulj 我认为在将relusquare 应用于np.array 时,python 将遍历每个元素并应用 lambda 函数
  • @Raftel np.where 是矢量化的,而 [relu(a) for a in x] 是一个一个的,并且有创建 Python 列表的开销。特别是对于较大的数组,np.where 更快。

标签: python python-3.x numpy


【解决方案1】:
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])

lambda 只是一个函数定义,相当于做:

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

函数层不添加任何迭代。进行元素迭代的是 x 数组的 power 方法。

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

同样relu 不添加任何迭代;它是标量 python if/else 子句。

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

它可以通过列表理解应用于x的元素:

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

数组有一个lt 方法,所以:

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

可以masked方式使用:

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])

或通过where

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

where 也不是迭代器。它实际上与 [17][18] 行相同。

if 表达式中使用数组相当于尝试将其转换为标量布尔值:

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()

它的工作原理是数组只有一个元素,否则会引发这种歧义错误:

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

但对于“空”数组:

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

但测试“空”列表是可以的:

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

【讨论】:

  • 感谢您的详细解答。
猜你喜欢
  • 2017-07-10
  • 2016-06-14
  • 2014-01-03
  • 2022-08-18
  • 1970-01-01
  • 2020-04-06
  • 2021-08-05
  • 2022-01-14
  • 1970-01-01
相关资源
最近更新 更多