我有一個稱爲dists的距離數組。我想選擇介於兩個值之間的dists。我寫了下面的代碼行做到這一點:Numpy功能多個條件
dists[(np.where(dists >= r)) and (np.where(dists <= r + dr))]
然而,這僅選擇爲條件
(np.where(dists <= r + dr))
如果我用它工作正常臨時變量做的命令順序。爲什麼上面的代碼不起作用,我如何才能使它工作?
乾杯
我有一個稱爲dists的距離數組。我想選擇介於兩個值之間的dists。我寫了下面的代碼行做到這一點:Numpy功能多個條件
dists[(np.where(dists >= r)) and (np.where(dists <= r + dr))]
然而,這僅選擇爲條件
(np.where(dists <= r + dr))
如果我用它工作正常臨時變量做的命令順序。爲什麼上面的代碼不起作用,我如何才能使它工作?
乾杯
在你的具體情況將只是給你兩個標準更改爲一個標準的最好方法:
dists[abs(dists - r - dr/2.) <= dr/2.]
它僅創建一個布爾數組,而在我看來是比較容易閱讀,因爲它說,是dist
在dr
或r
?(雖然我會重新定義r
是您感興趣的地區的中心而不是開始,所以r = r + dr/2.
)但是這並不能回答你的問題。
回答你的問題:
你實際上並不需要where
,如果你只是想篩選出不符合您的標準的dists
元素:
dists[(dists >= r) & (dists <= r+dr)]
因爲&
會給你一個元素and
(括號是必要的)。
或者,如果你想使用where
出於某種原因,你可以這樣做:
dists[(np.where((dists >= r) & (dists <= r + dr)))]
爲什麼:
它不工作的原因,是因爲np.where
返回一個列表的索引,而不是布爾數組。您正試圖在兩個數字列表之間獲得and
,這當然沒有您期望的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. ])
或簡單地使用布爾數組索引原始數組使用fancy indexing
In [241]: dists[(dists >= r) & (dists <= r + dr)]
Out[241]: array([ 5. , 5.5, 6. ])
我已經制定了這個簡單的例子
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.intersect1d(np.where(dists >= r)[0],np.where(dists <= r + dr)[0])
由於接受的答案解釋這個問題非常好。你也可以使用numpy logical functions哪個更適合這裏的多個條件:
np.where(np.logical_and(np.greater_equal(dists,r),np.greater_equal(dists,r + dr)))
我喜歡用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
清晰輸出。但那是你的電話:)
希望它有幫助。
在這種情況下不需要迭代。 NumPy具有布爾索引。 – M456 2013-05-02 17:12:58