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


69

我必须计算矩阵(二维数组)中大于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

o31 是一幅图像,我将其转换为矩阵,然后查找值。

我的问题是,有没有更简单的方法可以做到这一点?


1
这不是只打印小于200的值,而不是实际值吗?
Burhan Khalid 2012年

是的。我只需要所有值的总和,而不是实际值本身。
gran_profaci 2012年

您也不会在这里得到总数。设置za为空列表za = [],然后za.append(p31[i,j])最终退出for循环print sum(za);但我敢肯定,因为您使用的是numpy,所以有更好的方法。
Burhan Khalid 2012年

我更新了您的问题标题,以使您的问题更加清楚(据我的评论和回答所理解。如果错误,您可以对其进行重新编辑。)
bmu 2012年

Answers:


90

numpy.where功能是您的朋友。因为它是为充分利用数组数据类型而实现的,所以对于大图像,您应该注意到与提供的纯python解决方案相比,速度有所提高。

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

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

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

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

从那里获取的确切位置取决于您想要的结果形式。


12
谢谢...但是我需要值的总数,而不是值本身..我应该做sum(numpy.where(data <200))吗?
gran_profaci 2012年

7
如果您需要OF的数量而不是总和,则可以执行len(numpy.where(data <200))
jimh

1
如果条件更改为> 0,则它将返回(array([0,0,1,1]),array([0,1,0,1])),这是什么意思?还是一个错误?
hihell

该方法不必要地复杂。@neonneo的方法更加简单明了,并且在回答问题方面做得更好。
防水

@jimh对我来说np.where返回一个元组,必须做len(np.where(...)[0])
user1114

94

对于布尔数组,这非常简单:

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

26

有很多方法可以做到这一点,例如展平和过滤或简单地枚举,但我认为使用布尔/掩码数组是最简单的方法(而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

2
timeit y[b]省略了在过滤器中完成的计算中的一半代码。%timeit y[y>200]是等价的。
疯狂物理学家

8

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

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

这只是常规的布尔索引。
疯狂物理学家

3

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

n = len(matrix[matrix > x])

布尔索引返回一个仅包含满足条件(矩阵> x)的元素的数组。然后len()计算这些值。


1
您可能需要解释为什么这样做。__gt__我想超载了,但这不是显而易见的。
阿德里安W
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.