如何在条件上对ndarray使用numpy.mean()?

时间:2017-02-14 11:38:23

标签: python numpy

有没有办法过滤ndarray的值,同时取一个特定轴的平均值? 这是MWE:

import numpy as np
import random

arr = np.ndarray((10, 5))

for i in range(10):
    for j in range(5):
        arr[i, j] = random.randint(0, 5)

mean = arr[arr < 0.7].mean(axis = 0)

这不起作用,因为arr[arr < 0.7]是阵列的扁平化。

还有其他想法吗?

2 个答案:

答案 0 :(得分:1)

一种方法是使用通过与给定阈值进行比较而设置的有效掩码,获取axis=0中元素的总和,并将它们除以参与求和的有效元素的数量,以获得期望的average值来自有效值。

因此,实现将是这样的 -

mask = arr < thresh
out = np.einsum('ij,ij->j',arr,mask)/mask.sum(axis = 0)

逐步运行示例 -

In [49]: arr
Out[49]: 
array([[ 4.,  3.,  2.,  5.,  0.],
       [ 1.,  1.,  5.,  1.,  4.],
       [ 2.,  5.,  1.,  2.,  4.],
       [ 0.,  4.,  0.,  0.,  1.],
       [ 2.,  3.,  0.,  1.,  2.],
       [ 4.,  5.,  3.,  3.,  0.],
       [ 5.,  0.,  0.,  4.,  1.],
       [ 4.,  2.,  0.,  5.,  3.],
       [ 5.,  0.,  0.,  5.,  0.],
       [ 0.,  1.,  0.,  2.,  1.]])

In [50]: thresh = 4

In [51]: mask = arr < thresh

In [52]: mask
Out[52]: 
array([[False,  True,  True, False,  True],
       [ True,  True, False,  True, False],
       [ True, False,  True,  True, False],
       [ True, False,  True,  True,  True],
       [ True,  True,  True,  True,  True],
       [False, False,  True,  True,  True],
       [False,  True,  True, False,  True],
       [False,  True,  True, False,  True],
       [False,  True,  True, False,  True],
       [ True,  True,  True,  True,  True]], dtype=bool)

In [53]: np.einsum('ij,ij->j',arr,mask)
Out[53]: array([  5.,  10.,   6.,   9.,   8.])

In [54]: np.einsum('ij,ij->j',arr,mask)/mask.sum(axis = 0)
Out[54]: array([ 1.        ,  1.42857143,  0.66666667,  1.5       ,  1.        ])

谈论&#34;可读性&#34;或者,我们可以使用简单的元素乘法和求和,就像这样 -

out = (arr*mask).sum(axis = 0)/mask.sum(axis = 0)

答案 1 :(得分:1)

你可以在这里使用蒙面数组:

ok_mask = arr < 0.7
np.ma.masked_where(~ok_mask, arr).mean(axis=0)

如果排除了沿0轴的整个切片,那么这将在该条目中返回np.masked