首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NumPy分段与NumPy,其中

NumPy分段与NumPy,其中
EN

Stack Overflow用户
提问于 2017-06-23 00:57:41
回答 2查看 861关注 0票数 0

在哪些特定情况下,在计算数组上的分段函数时,np.piecewise会比np.where更方便(更少冗长)或计算速度更快?我很难看到这样的情况,而且我似乎经常遇到使用where计算分段函数的情况。

无论片断多少,np.piecewise似乎都更冗长:

代码语言:javascript
复制
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

它的速度也要慢得多:

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-06-23 03:31:45

如果它能帮助你做出决定,下面是piecewise正在做的事情:

代码语言:javascript
复制
In [2]: b = np.arange(10,20,dtype=float)

定义两个输入列表;请注意,现在已评估了条件。

代码语言:javascript
复制
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只是在两个列表上迭代,并将值赋给目标数组:

代码语言:javascript
复制
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是相似的。在像这样的简单计算中,它可能没有太大的区别。

代码语言:javascript
复制
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。分段的选择性评估会更好。

冗长不应该是一个重要的衡量标准。我们已经花了更多的时间来输入问题和答案。在工作代码中,冗长的代码可以隐藏在函数中。从长远来看,可读性更重要。

票数 1
EN

Stack Overflow用户

发布于 2017-06-23 01:31:40

如果计算很慢,piecewise会更快,因为只计算所需的值。

较短的版本:

代码语言:javascript
复制
d = np.piecewise(b, [b<11, (b>=11)&(b<14)], [1, lambda x: x**2, lambda x: x/2])
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44705368

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档