Numpyfunction多个条件
我有一个称为dists的距离数组。 我想select两个值之间的dists。 我写了下面这行代码来做到这一点:
dists[(np.where(dists >= r)) and (np.where(dists <= r + dr))]
但是,这只能select条件
(np.where(dists <= r + dr))
如果我通过使用一个临时variables顺序执行命令,它工作正常。 为什么上面的代码不起作用,我如何才能使它工作?
干杯
在你的具体情况下 ,最好的办法就是把你的两个标准改为一个标准:
dists[abs(dists - r - dr/2.) <= dr/2.]
它只创build一个布尔数组,在我看来更容易阅读,因为它说, dr
或r
? (尽pipe我将r
重新定义为你感兴趣的区域的中心而不是开始,所以r = r + dr/2.
)但是这并不能回答你的问题。
你的问题的答案是:
如果你只是想过滤不符合标准的dists
元素,你实际上并不需要where
:
dists[(dists >= r) & (dists <= r+dr)]
因为&
会给你一个元素and
(括号是必要的)。
或者,如果您出于某种原因想要使用,可以这样做:
dists[(np.where((dists >= r) & (dists <= r + dr)))]
为什么:
它不工作的原因是因为np.where
返回一个索引列表,而不是一个布尔数组。 你正在尝试获取两个数字列表,这当然没有你期望的True
/ False
值。 如果a
和b
都是True
值,则a and b
返回b
。 所以说[0,1,2] and [2,3,4]
就会给你[2,3,4]
。 这是在行动:
In [230]: dists = np.arange(0,10,.5) In [231]: r = 5 In [232]: dr = 1 In [233]: np.where(dists >= r) Out[233]: (array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),) In [234]: np.where(dists <= r+dr) Out[234]: (array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]),) In [235]: np.where(dists >= r) and np.where(dists <= r+dr) Out[235]: (array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]),)
例如,您期望比较的只是布尔数组
In [236]: dists >= r Out[236]: array([False, False, False, False, False, False, False, False, False, False, True, True, True, True, True, True, True, True, True, True], dtype=bool) In [237]: dists <= r + dr Out[237]: array([ True, True, True, True, True, True, True, True, True, True, True, True, True, False, False, False, False, False, False, False], dtype=bool) In [238]: (dists >= r) & (dists <= r + dr) Out[238]: array([False, False, False, False, False, False, False, False, False, False, True, True, True, False, False, False, False, False, False, False], dtype=bool)
现在你可以在组合的布尔数组上调用np.where
:
In [239]: np.where((dists >= r) & (dists <= r + dr)) Out[239]: (array([10, 11, 12]),) In [240]: dists[np.where((dists >= r) & (dists <= r + dr))] Out[240]: array([ 5. , 5.5, 6. ])
或者使用花哨的索引来简单地用布尔数组索引原始数组
In [241]: dists[(dists >= r) & (dists <= r + dr)] Out[241]: array([ 5. , 5.5, 6. ])
由于接受的答案很好地解释了这个问题。 你也可以使用numpy逻辑函数在这里更适合多种情况:
np.where(np.logical_and(np.greater_equal(dists,r),np.greater_equal(dists,r + dr)))
尝试:
np.intersect1d(np.where(dists >= r)[0],np.where(dists <= r + dr)[0])
我已经制定了这个简单的例子
import numpy as np ar = np.array([3,4,5,14,2,4,3,7]) print [X for X in list(ar) if (X >= 3 and X <= 6)] >>> [3, 4, 5, 4, 3]
我喜欢使用np.vectorize
来完成这些任务。 考虑以下几点:
>>> # function which returns True when constraints are satisfied. >>> func = lambda d: d >= r and d<= (r+dr) >>> >>> # Apply constraints element-wise to the dists array. >>> result = np.vectorize(func)(dists) >>> >>> result = np.where(result) # Get output.
您也可以使用np.argwhere
而不是np.where
来清除输出。 但那是你的呼唤:)
希望它有帮助。