我必须计算矩阵(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
o31
是一张图片,我将其转换为矩阵,然后找到值。
我的问题是,有更简单的方法吗?
答案 0 :(得分:70)
布尔数组非常简单:
p31 = numpy.asarray(o31)
za = (p31 < 200).sum() # p31<200 is a boolean array, so `sum` counts the number of True elements
答案 1 :(得分:69)
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])
你从哪里拿到它将取决于你想要的结果形式。
答案 2 :(得分:20)
有很多方法可以实现这一点,例如flatten-and-filter或简单枚举,但我认为使用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
答案 3 :(得分:7)
这是一个使用花式索引并将实际值作为中间值的变体:
p31 = numpy.asarray(o31)
values = p31[p31<200]
za = len(values)
答案 4 :(得分:2)
要计算任何numpy数组中大于x的值的数量,可以使用:
n = len(matrix[matrix > x])
答案 5 :(得分:0)
您可以使用numpy.count_nonzero,将整体转换为一行:
za = numpy.count_nonzero(numpy.asarray(o31)<200) #as written in the code