2017-02-14 53 views
2

有没有一种方法可以过滤ndarray的值,并同时考虑某个轴的平均值? 这里是MWE:如何在一个条件的ndarray上使用numpy.mean()?

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]工作是阵列的flattes。

还有其他想法吗?

+0

如果你说没有工作,你有什么预期的结果返回np.masked? – kazemakase

+0

这个计算全局平均值为'arr [condition]'返回一个平坦的数组。我期望得到5个平均值的列表。 – Schneemannbruzzler

+0

然后Divakar的答案应该适合你。或者,你可以用NaN替换你不想要的值,并使用'np.nanmean':1. arr [arr <0.7] = np.nan' 2.'mean = np.nanmean(arr,axis = 0) '但我认为另一种解决方案更快更清洁(但可能稍微有点不太可读)。 – kazemakase

回答

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.  ]) 

会说话的“可读性”,或者,我们可以使用简单的elementwise乘法并总结,像这样 -

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

谢谢!它工作得很好。我不知道有关爱因斯坦。 [Documentation einsum](https://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.einsum.html) – Schneemannbruzzler

+0

@Schneemannbruzzler是的!总是一个很好的习惯来跟随文档,并尝试理解代码,从而逃避“可读性”的谈话! – Divakar

1

你可以在这里使用蒙面阵列:

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

如果沿0轴整片被排除在外,那么这将在该条目

+1

在帖子中认为值得一提的是比较运算符被倒过来以避免混淆。另外,我想我们需要在那里使用'> ='与'<'相对。 – Divakar