2012-10-21 48 views
31

我有在大於200計數矩陣中的所有值大於一個值

我寫下該代碼,這一個矩陣(2- d陣列)來計算所有的值是:

za=0 
p31 = numpy.asarray(o31) 
for i in range(o31.size[0]): 
    for j in range(o32.size[1]): 
     if p31[i,j]<200: 
      za=za+1 
print za 

o31是一個圖像,我將它轉換成矩陣,然後找到值。

我的問題是,有沒有簡單的方法來做到這一點?

+1

這是不是隻打印小於200的值的數量,而不是實際值? –

+0

是的..我只需要所有值的總和而不是實際值本身。 –

+0

這裏你也沒有得到總數。將'za'設置爲一個空列表'za = []',然後'za.append(p31 [i,j])',最後從for循環中'print sum(za)';但是我確信自從你使用numpy以後有更好的方法。 –

回答

45

numpy.where功能是你的朋友。因爲它是爲了充分利用數組數據類型而實現的,所以對於大型圖像,您應該注意到您提供的純Python解決方案的速度提升。

使用numpy.where直接將產生boolean值的掩碼錶明一定值是否符合您的條件:

>>> data 
array([[1, 8], 
     [3, 4]]) 
>>> numpy.where(data > 3) 
(array([0, 1]), array([1, 1])) 

而且面膜可以用來索引數組直接獲取實際值:

>>> data[ numpy.where(data > 3) ] 
array([8, 4]) 

你究竟從哪裏拿它取決於你想要什麼樣的結果。

+6

謝謝...但是我需要的是總數值,而不是值本身..我應該做sum(numpy.where(數據<200))? –

+0

如果要值的數量,而不是總和,你會做LEN(numpy.where(數據<200)) – jimh

+0

如果條件改變爲> 0,則它會返回(陣列([0,0,1,1 ]),數組([0,1,0,1])),這是什麼意思?或者它是一個錯誤? – hihell

15

有很多方法可以達到這個目的,比如f薄金屬片和過濾器或簡單地列舉,但我認爲使用Boolean/mask array是最簡單的一個(IIRC更快的一個):

>>> y = np.array([[123,24123,32432], [234,24,23]]) 
array([[ 123, 24123, 32432], 
     [ 234, 24, 23]]) 
>>> b = y > 200 
>>> b 
array([[False, True, True], 
     [ True, False, False]], dtype=bool) 
>>> y[b] 
array([24123, 32432, 234]) 
>>> len(y[b]) 
3 
>>>> y[b].sum() 
56789 

更新

由於nneonneo已經回答了,如果你希望的是,通過門限部件的數量,你可以簡單地做:

>>>> (y>200).sum() 
3 

這是一個簡單的解決方案。


filter速度比較:

### use boolean/mask array ### 

b = y > 200 

%timeit y[b] 
100000 loops, best of 3: 3.31 us per loop 

%timeit y[y>200] 
100000 loops, best of 3: 7.57 us per loop 

### use filter ### 

x = y.ravel() 
%timeit filter(lambda x:x>200, x) 
100000 loops, best of 3: 9.33 us per loop 

%timeit np.array(filter(lambda x:x>200, x)) 
10000 loops, best of 3: 21.7 us per loop 

%timeit filter(lambda x:x>200, y.ravel()) 
100000 loops, best of 3: 11.2 us per loop 

%timeit np.array(filter(lambda x:x>200, y.ravel())) 
10000 loops, best of 3: 22.9 us per loop 

*** use numpy.where *** 

nb = np.where(y>200) 
%timeit y[nb] 
100000 loops, best of 3: 2.42 us per loop 

%timeit y[np.where(y>200)] 
100000 loops, best of 3: 10.3 us per loop 
+0

'timeit Y [B]'從過濾器所作的計算中省略一半的代碼。 '%timeit y [y> 200]'是等價的。 –

44

這是非常簡單的用布爾數組:

p31 = numpy.asarray(o31) 
za = (p31 < 200).sum() # p31<200 is a boolean array, so `sum` counts the number of True elements 
6

下面是一個使用花式索引和具有的實際值作爲中間的變體:

p31 = numpy.asarray(o31) 
values = p31[p31<200] 
za = len(values) 
+0

這只是普通的布爾索引。 –

相關問題