2016-01-21 93 views
2

給定2個numpy不等大小的數組:A(預分類數據集)和B(查詢值列表)。我想找到在數組A中的最接近的「下」鄰居的下面陣列B.實施例的代碼的每個元素:查找python中兩個列表中最接近的鄰居的索引

import numpy as np 

A = np.array([0.456, 2.0, 2.948, 3.0, 7.0, 12.132]) #pre-sorted dataset 
B = np.array([1.1, 1.9, 2.1, 5.0, 7.0]) #query values, not necessarily sorted 
print A.searchsorted(B) 
# RESULT: [1 1 2 4 4] 
# DESIRED: [0 0 1 3 4] 

在這個例子中,B [0]的最近的鄰居是A [0]和A [1]。它最接近A [1],這就是爲什麼searchsorted將索引1作爲匹配返回,但我想要的是索引爲0的較低鄰居。對於B [1:4]和B [4]應該與A [4],因爲兩個值是相同的。

我可以做一些笨重的是這樣的:

desired = [] 
for b in B: 
    id = -1 
    for a in A: 
     if a > b: 
      if id == -1: 
       desired.append(0) 
      else: 
       desired.append(id) 
      break 

     id+=1 

print desired 
# RESULT: [0, 0, 1, 3, 4] 

但還有得是與numpy的寫一個漂亮更簡潔的方式。我想保持我的解決方案在numpy,因爲我正在處理大型數據集,但我願意接受其他選擇。

回答

3

您可以引入可選參數side並將其設置爲'right',如docs中所述。然後,減去最終指數通過結果爲1所需的輸出,像這樣 -

A.searchsorted(B,side='right')-1 

採樣運行 -

In [63]: A 
Out[63]: array([ 0.456, 2. , 2.948, 3. , 7. , 12.132]) 

In [64]: B 
Out[64]: array([ 1.1, 1.9, 2.1, 5. , 7. ]) 

In [65]: A.searchsorted(B,side='right')-1 
Out[65]: array([0, 0, 1, 3, 4]) 

In [66]: A.searchsorted(A,side='right')-1 # With itself 
Out[66]: array([0, 1, 2, 3, 4, 5]) 
+1

在大型陣列上快得多!謝謝! – Fnord

+0

@Davikar實際上有一個不好的邊緣情況:如果兩個數組的最後一項都是相同的值,返回的索引是0(-1,沒有.clip(min = 0)....所以例如,如果您運行數組本身就像:((A [:,無]> A).argmax(0)-1).clip(min = 0)結果將是數組([0,1,2,3,4,0] ),我想要的最後一個項目是5 – Fnord

+0

@Fnord請檢查編輯 – Divakar

1

以下是一種方法。 np.argmax在遇到的第一個True時停止,所以只要A被排序,這就提供了期望的結果。

[np.argmax(A>b)-1 for b in B] 

編輯:我得到了最初的不平等錯誤,它現在起作用了。

+0

謝謝!很好,很簡潔。我會用你的想法,除非有人提出一個比迭代B元素更快的想法,如果B的元素小於A的最小元素,你的循環返回-1的索引,所以我修改它以限制它0,這是我想要的:i = np.array([np.argmax(A> b)-1 for b in B])。clip(min = 0) – Fnord