2014-10-03 61 views
3

我有在Python阵列像这样:如何在满足多个条件的numpy数组中找到索引?

实施例:

>>> scores = numpy.asarray([[8,5,6,2], [9,4,1,4], [2,5,3,8]]) 
>>> scores 
array([[8, 5, 6, 2], 
    [9, 4, 1, 4], 
    [2, 5, 3, 8]]) 

我想找到所有[row, col]指数在scores其中值是:

1)的最小在其

2)大于阈值

3)至多是下一个la的.8倍在行中的rgest值

我想尽可能有效地做到这一点,最好是没有任何循环。我一直在努力争取一段时间,所以你可以提供任何帮助将不胜感激!

+1

是不是进球数1)和3)相冲突? – JB333 2014-10-03 00:29:44

+0

@ JB333也许这是一个技巧性的问题,答案是总是返回一个空数组(没有任何循环)。 ;-) – Carsten 2014-10-03 00:56:21

回答

2

它应该去的东西沿着

In [1]: scores = np.array([[8,5,6,2], [9,4,1,4], [2,5,3,8]]); threshold = 1.1; scores 
Out[1]: 
array([[8, 5, 6, 2], 
     [9, 4, 1, 4], 
     [2, 5, 3, 8]]) 

In [2]: part = np.partition(scores, 2, axis=1); part 
Out[2]: 
array([[2, 5, 6, 8], 
     [1, 4, 4, 9], 
     [2, 3, 5, 8]]) 

In [3]: row_mask = (part[:,0] > threshold) & (part[:,0] <= 0.8 * part[:,1]); row_mask 
Out[3]: array([ True, False, True], dtype=bool) 

In [4]: rows = row_mask.nonzero()[0]; rows 
Out[4]: array([0, 2]) 

In [5]: cols = np.argmin(scores[row_mask], axis=1); cols 
Out[5]: array([3, 0]) 

线那一刻,如果你正在寻找的实际坐标对,你可以zip他们:

In [6]: coords = zip(rows, cols); coords 
Out[6]: [(0, 3), (2, 0)] 

或者,如果你打算看看这些元素,你可以直接使用它们:

In [7]: scores[rows, cols] 
Out[7]: array([2, 2]) 
+0

非常感谢!那是我正在寻找的那种东西。 – jmanring220 2014-10-03 14:12:41

1

我认为你将很难做到这一点没有任何for循环(或至少是执行这样一个循环,但可能是伪装它作为别的东西),看看操作只取决于行,并且您想为每行执行此操作。这不是最有效的(什么是可能取决于条件2和3的频率为真),但是这将工作:

import heapq 
threshold = 1.5 
ratio = .8 
scores = numpy.asarray([[8,5,6,2], [9,4,1,4], [2,5,3,8]]) 

found_points = [] 
for i,row in enumerate(scores): 
    lowest,second_lowest = heapq.nsmallest(2,row) 
    if lowest > threshold and lowest <= ratio*second_lowest: 
     found_points.append([i,numpy.where(row == lowest)[0][0]]) 

你得到(为例子):

found_points = [[0, 3], [2, 0]] 
+0

谢谢@ JB333!那也行得通。 – jmanring220 2014-10-03 14:12:09