[英]NumPy piecewise versus NumPy where
In what specific situations would np.piecewise
be more convenient (less verbose) or computationally speeder than np.where
, in evaluating a piecewise function on an array? 在什么特定情况下, np.piecewise
在计算数组上的分段函数时会比np.where
更方便(较不冗长)或计算速度更快? I'm having trouble seeing such a case, and I seem to run across piecewise functions being evaluated more often with where
. 我在遇到这种情况时遇到麻烦,而且似乎遇到了更多使用where
进行评估的分段函数。
np.piecewise
seems to be more verbose regardless of number of pieces: 无论件数多少, np.piecewise
似乎都比较冗长:
import numpy as np
b = np.arange(10, 20, dtype=np.float)
# 2 pieces - piecewise is more verbose
a = np.piecewise(b, [b<14, b>=14], [lambda x: x**2, lambda x: x/2])
c = np.where(b>=14, b/2, b ** 2)
print(np.array_equal(a, c))
True
# 3 pieces - piecewise still more verbose (won't it always be?)
d = np.piecewise(b, [b<11, np.logical_and(b>=11, b<14), b>=14],
[1, lambda x: x**2, lambda x: x/2])
e = np.where(b>=14, b/2, np.where(b>=11, b**2, 1))
print(np.array_equal(d, e))
True
It is also significantly slower: 它也明显慢一些:
from timeit import timer
# variables above redefined as callables with no args
print('times:\n a: %d, c: %d, d: %d, e: %d'
% (timeit(a), timeit(c), timeit(d), timeit(e)))
times:
a: 17, c: 4, d: 21, e: 7
piecewise
is faster, if the calculation is slow, because only the values, that are needed are calculated. 如果计算速度较慢,则piecewise
速度会更快,因为只会计算所需的值。
Shorter version: 较短的版本:
d = np.piecewise(b, [b<11, (b>=11)&(b<14)], [1, lambda x: x**2, lambda x: x/2])
In case it helps you decide, here's what piecewise
is doing: 在情况下,它可以帮助你确定,这里就是piecewise
做:
In [2]: b = np.arange(10,20,dtype=float)
define the 2 input lists; 定义2个输入列表; note that condition(s) are evaluated now. 请注意,现在评估条件。
In [12]: condlist = [b<14, b>=14]
In [13]: condlist
Out[13]:
[array([ True, True, True, True, False, False, False, False, False, False], dtype=bool),
array([False, False, False, False, True, True, True, True, True, True], dtype=bool)]
In [14]: fnlist = [lambda x: x**2, lambda x: x/2]
piecewise
just iterates on the 2 lists, and assigns values to the target array: piecewise
迭代2个列表,并将值分配给目标数组:
In [15]: a = np.zeros_like(b)
In [16]: for k in range(len(condlist)):
...: idx = condlist[k]
...: a[idx] = fnlist[k](b[idx])
...:
In [17]: a
Out[17]:
array([ 100. , 121. , 144. , 169. , 7. , 7.5, 8. , 8.5,
9. , 9.5])
In [18]: np.piecewise(b, condlist, fnlist)
Out[18]:
array([ 100. , 121. , 144. , 169. , 7. , 7.5, 8. , 8.5,
9. , 9.5])
This pair of where
is similar, except the the fnlist
calls are applied to the whole of b
rather than a subset. 除了fnlist
调用应用于整个b
而不是子集之外,这对where
相似。 In simple calculations like this it probably doesn't make much difference. 在像这样的简单计算中,它可能并没有太大区别。
In [21]: a = np.where(condlist[0], fnlist[0](b),0)
In [22]: a = np.where(condlist[1], fnlist[1](b),a)
In [23]: a
Out[23]:
array([ 100. , 121. , 144. , 169. , 7. , 7.5, 8. , 8.5,
9. , 9.5])
In some cases it is wrong to evaluate a function over the whole range of b
values - for example if it involves division by 0. The selective evaluation of piecewise would be better. 在某些情况下,在b
值的整个范围内评估函数是错误的-例如,如果涉及除以0的情况。分段的选择性评估会更好。
Verbosity shouldn't be a significant measure. 详细程度不是一个重要的衡量指标。 We've already spent more time typing that question and answers. 我们已经花了更多时间输入问题和答案。 In working code, wordy code can be hidden in functions. 在工作代码中,冗长的代码可以隐藏在函数中。 Readability is more important in the long run. 从长远来看,可读性更为重要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.