在哪些特定情况下,在计算数组上的分段函数时,np.piecewise会比np.where更方便(更少冗长)或计算速度更快?我很难看到这样的情况,而且我似乎经常遇到使用where计算分段函数的情况。
无论片断多少,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它的速度也要慢得多:
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发布于 2017-06-23 03:31:45
如果它能帮助你做出决定,下面是piecewise正在做的事情:
In [2]: b = np.arange(10,20,dtype=float)定义两个输入列表;请注意,现在已评估了条件。
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只是在两个列表上迭代,并将值赋给目标数组:
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])除了fnlist调用应用于整个b而不是子集之外,这对where是相似的。在像这样的简单计算中,它可能没有太大的区别。
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])在某些情况下,在整个b值范围内计算函数是错误的-例如,如果它涉及除以0。分段的选择性评估会更好。
冗长不应该是一个重要的衡量标准。我们已经花了更多的时间来输入问题和答案。在工作代码中,冗长的代码可以隐藏在函数中。从长远来看,可读性更重要。
发布于 2017-06-23 01:31:40
如果计算很慢,piecewise会更快,因为只计算所需的值。
较短的版本:
d = np.piecewise(b, [b<11, (b>=11)&(b<14)], [1, lambda x: x**2, lambda x: x/2])https://stackoverflow.com/questions/44705368
复制相似问题