为了用Python编写“分段函数”,我通常会使用if
(以控制流或三元运算符的形式)。
def spam(x):
return x+1 if x>=0 else 1/(1-x)
现在,使用NumPy的口头禅是避免对单个值进行处理,而倾向于矢量化以提高性能。因此,我认为这样的选择将是更可取的:正如莱昂所说,以下错误
def eggs(x):
y = np.zeros_like(x)
positive = x>=0
y[positive] = x+1
y[np.logical_not(positive)] = 1/(1-x)
return y
(如果我错过了这里的内容,请纠正我,因为坦率地说,我觉得这很丑。)
现在,当然eggs
会只有当工作x
实际上是一个NumPy的阵列,否则x>=0
只是产生一个布尔值,它不能被用于索引(至少不会做正确的事)。
有没有一种好的方法来编写看起来更像spam
但可以在Numpy数组上正常工作的代码,还是我应该使用vectorize(spam)
?
使用np.where
。但是,即使对于纯数字输入,您也会得到一个数组作为输出。
def eggs(x):
y = np.asarray(x)
return np.where(y>=0, y+1, 1/(1-y))
这适用于数组和纯数字:
>>> eggs(5)
array(6.0)
>>> eggs(-3)
array(0.25)
>>> eggs(np.arange(-3, 3))
/home/praveen/.virtualenvs/numpy3-mkl/bin/ipython3:2: RuntimeWarning: divide by zero encountered in true_divide
array([ 0.25 , 0.33333333, 0.5 , 1. , 2. , 3. ])
>>> eggs(1)
/home/praveen/.virtualenvs/numpy3-mkl/bin/ipython3:3: RuntimeWarning: divide by zero encountered in long_scalars
# -*- coding: utf-8 -*-
array(2.0)
正如阿伊汉(Ayhan)所说,这引起了警告,因为1/(1-x)
对整个范围进行了评估。但是警告仅仅是:警告。如果您知道自己在做什么,则可以忽略该警告。在这种情况下,您仅从1/(1-x)
永远不能选择的索引中进行选择inf
,因此很安全。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句