计算矩阵中大于值的所有值

gra*_*aci 57 python arrays coding-style numpy pixel

我必须计算矩阵(2-d数组)中大于200的所有值.

我为此写下的代码是:

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
Run Code Online (Sandbox Code Playgroud)

o31 是一个图像,我将其转换为矩阵,然后找到值.

我的问题是,有更简单的方法吗?

nne*_*neo 76

布尔数组非常简单:

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

  • 我想这应该是最重要的答案。`np.where` 显然也可以工作,但提供了此处不需要的附加信息,使得答案有点不那么简单,并且性能有点慢 (4认同)

abo*_*ght 75

这个numpy.where功能是你的朋友.因为它的实现是为了充分利用数组数据类型,对于大型图像,你应该注意到你提供的纯python解决方案的速度提升.

直接使用numpy.where会产生一个布尔掩码,指示某些值是否符合您的条件:

>>> data
array([[1, 8],
       [3, 4]])
>>> numpy.where( data > 3 )
(array([0, 1]), array([1, 1]))
Run Code Online (Sandbox Code Playgroud)

并且掩码可用于直接索引数组以获取实际值:

>>> data[ numpy.where( data > 3 ) ]
array([8, 4])
Run Code Online (Sandbox Code Playgroud)

你从哪里拿到它将取决于你想要的结果形式.

  • 谢谢...但我需要值的总数,而不是值本身..我应该总和(numpy.where(数据<200))? (10认同)
  • 如果你想要数字OF值,而不是总和,你会做len(numpy.where(数据<200)) (4认同)

K Z*_*K Z 22

有许多方法可以实现这一点,例如flatten-and-filter或简单枚举,但我认为使用Boolean/mask数组是最简单的(而且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
Run Code Online (Sandbox Code Playgroud)

更新:

正如nneonneo所回答的那样,如果你想要的只是通过阈值的元素数量,你可以简单地做:

>>>> (y>200).sum()
3
Run Code Online (Sandbox Code Playgroud)

这是一个更简单的解决方案.


速度比较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
Run Code Online (Sandbox Code Playgroud)

  • “ timey y [b]”省略了在过滤器中完成的计算的一半代码。%timeit y [y&gt; 200]是等效的。 (2认同)

Kar*_*rol 7

这是一个使用花式索引并将实际值作为中间值的变体:

p31 = numpy.asarray(o31)
values = p31[p31<200]
za = len(values)
Run Code Online (Sandbox Code Playgroud)


Ric*_*ter 6

要计算任何 numpy 数组中大于 x 的值的数量,您可以使用:

n = len(matrix[matrix > x])
Run Code Online (Sandbox Code Playgroud)

布尔索引返回一个数组,该数组仅包含满足条件 (matrix > x) 的元素。然后 len() 对这些值进行计数。