2017-02-09 54 views
1

假設我有一個按第一個值排序的元組的排序數組。我想找到第一個索引,其中元組的第一個元素的條件成立。即如何替換下面的代碼在python中用等效的matlab代替循環

test_array = [(1,2),(3,4),(5,6),(7,8),)(9,10)] 
min_value = 5 
index = 0 
for c in test_array: 
     if c[0] > min_value: 
      break 
     else: 
      index = index + 1 

與matlab的等價物找到了嗎?

即在這個循環結束時,我期望得到3,但我想使這更高效。我爲這個使用numpy罰款。我嘗試使用argmax但無濟於事。

感謝

+0

你不是說你想找到在條件成立,而不是第一個_last_指數?因爲這就是你在這裏做的。你可以添加一個簡單的例子,說明你如何在matlab中做到這一點,這樣我們可以更好地理解你在問什麼? – Anonymous

回答

4

由於列表是排序的,並且如果您知道第二個元素的最大可能值(或者只能有有1個元素具有相同的第一個值),你可以的元組的名單上應用bisect(返回列表排序插入位置)

import bisect 
test_array = [(1,2),(3,4),(5,6),(7,8),(9,10)] 
min_value = 5 

print(bisect.bisect_left(test_array,(min_value,10000))) 

硬編碼到10000是壞的,所以如果你只是有一個整數,你可以做到這一點,而不是:

print(bisect.bisect_left(test_array,(min_value+1,))) 

結果:3

,如果你有彩車(還與整數),你可以使用sys.float_info.epsilon這樣的:

print(bisect.bisect_left(test_array,(min_value*(1+sys.float_info.epsilon),))) 

O(log(n))複雜所以它不是一個簡單的for循環時,有很多因素要好得多。

+0

我不知道開張。優秀!謝謝。 – LostInTheFrequencyDomain

+0

是的,這是一個很好的。看我的編輯。根據數據,我以前的答案可能會失敗。 –

+0

看來你可以使用None作爲第二個參數而不是1000。 – LostInTheFrequencyDomain

0

您可以使用numpy的,以表明遵守條件的元素,然後用argmax(),拿到第一個

import numpy 
test_array = numpy.array([(1,2),(3,4),(5,6),(7,8),(9,10)]) 
min_value = 5 

print (test_array[:,0]>min_value).argmax() 

的指數,如果你想找到所有的服從條件的元素,使用可以替換作者:nonzero()[0]

+0

我會說這是過度殺傷 – Anonymous

+0

我希望條件成立的指數。此外,這返回(3,4)。我想返回(7,8)的索引。謝謝 – LostInTheFrequencyDomain

+0

對不起,有一個錯字。現在它運作 – yuval

0

一般來說,numpy的where的使用方式類似於MATLAB的find。但是,從效率角度來看,我無法控制I where只返回找到的第一個元素。所以,從計算的角度來看,你在這裏做的並不是低效的。

where相當於將

index = numpy.where(numpy.array([t[0] for t in test_array]) >= min_value) 
index = index[0] - 1