2014-06-21 34 views
1

我想形成包含k個最小值的指數在一個數組的數組:如何在多維數組中找到k個最小數的索引?

import heapq 
import numpy as np 

a= np.array([[1, 3, 5, 2, 3], 
     [7, 6, 5, 2, 4], 
     [2, 0, 5, 6, 4]]) 

[t[0] for t in heapq.nsmallest(2,enumerate(a[1]),lambda(t):t[1])] 
===[3, 4] 

但這種失敗:

[t[0] for t in heapq.nsmallest(2,enumerate(a.all()),lambda(t):t[1])] 

Traceback (most recent call last): 
    File "<pyshell#19>", line 1, in <module> 
    [t[0] for t in heapq.nsmallest(2,enumerate(a.all()),lambda(t):t[1])] 
TypeError: 'numpy.bool_' object is not iterable 
+0

你願意說明爲什麼它的失敗一些假設?這個問題是鈍的,因爲是 –

回答

1

可以使用numpy.ndenumerate用堆或者部分排序的建議由大衛:

a = np.array([[1, 3, 5, 2, 3], 
     [7, 6, 5, 2, 4], 
     [2, 0, 5, 6, 4]]) 
heap = [(v, k) for k,v in numpy.ndenumerate(npa)] 
heapq.heapify(heap) 
heapq.nsmallest(10, heap) # for k = 10 

,你會得到:

[(0, (2, 1)), 
(1, (0, 0)), 
(2, (0, 3)), 
(2, (1, 3)), 
(2, (2, 0)), 
(3, (0, 1)), 
(3, (0, 4)), 
(4, (1, 4)), 
(4, (2, 4)), 
(5, (0, 2))] 
+0

這是一個有趣的解決方案,但它似乎更慢。 Python stdlib在處理純數字運算方面並不是很優秀,因爲它允許對任意對象進行豐富的比較。 – Davidmh

+1

您可以使用index_tricks – Davidmh

+0

從平面數組中恢復二維索引。爲了提高速度,您可以使用只包含儘可能多元素的固定大小的堆,並根據需要單獨插入元組。那麼你不需要像最新的那些元素那樣使用頂級元素。堆解決方案的優點是易於理解:) – Emre

2

您的問題是在a.all()

[t[0] for t in heapq.nsmallest(2,enumerate(a.all()),lambda(t):t[1])] 

這檢查數組中所有元素的真實性,即False(因爲您有0)。

如果數組與k相比不太大,則可以使用.argsort來獲取值。在這裏,我將選擇最大的兩個位置的每一行:

print a.argsort()[:,:2] 

array([[0, 3], 
     [3, 4], 
     [1, 0]]) 

如果你想在全球最低的位置,壓平陣列firts:

a.flatten().argsort()[:2] 

如果陣列是非常大的,您可以使用np.argpartition獲得更好的性能,這將僅執行部分排序。

+0

非常感謝你Davidmh .. :) – Learner27

相關問題