【问题标题】:Numpy mean of nonzero values非零值的 Numpy 平均值
【发布时间】:2018-04-21 03:29:43
【问题描述】:

我有一个大小为 N*M 的矩阵,我想找到每一行的平均值。值从 1 到 5,没有任何值的条目设置为 0。但是,当我想使用以下方法找到平均值时,它给了我错误的平均值,因为它还计算了具有值的条目0.

matrix_row_mean= matrix.mean(axis=1)

我怎样才能得到只有非零值的平均值?

【问题讨论】:

    标签: python numpy mean numpy-ndarray


    【解决方案1】:

    获取每行中非零的计数,并将其用于平均每行的总和。因此,实现看起来像这样 -

    np.true_divide(matrix.sum(1),(matrix!=0).sum(1))
    

    如果您使用的是旧版本的 NumPy,则可以使用计数的浮点转换来替换 np.true_divide,就像这样 -

    matrix.sum(1)/(matrix!=0).sum(1).astype(float)
    

    示例运行 -

    In [160]: matrix
    Out[160]: 
    array([[0, 0, 1, 0, 2],
           [1, 0, 0, 2, 0],
           [0, 1, 1, 0, 0],
           [0, 2, 2, 2, 2]])
    
    In [161]: np.true_divide(matrix.sum(1),(matrix!=0).sum(1))
    Out[161]: array([ 1.5,  1.5,  1. ,  2. ])
    

    解决问题的另一种方法是将零替换为NaNs,然后使用np.nanmean,这将忽略那些NaNs,实际上是那些原始zeros,就像这样-

    np.nanmean(np.where(matrix!=0,matrix,np.nan),1)
    

    从性能的角度来看,我会推荐第一种方法。

    【讨论】:

    • np 没有属性 true_divide
    • 掩码数组方法很紧凑(但不一定更快):np.ma.masked_equal(matrix, 0).mean(axis=1)
    【解决方案2】:

    我将在这里详细介绍使用masked array 的更通用的解决方案。为了说明细节,让我们创建一个只有一个的下三角矩阵:

    matrix = np.tril(np.ones((5, 5)), 0)
    

    如果您对上述术语不清楚,则此矩阵如下所示:

      [[ 1.,  0.,  0.,  0.,  0.],
       [ 1.,  1.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  0.,  0.],
       [ 1.,  1.,  1.,  1.,  0.],
       [ 1.,  1.,  1.,  1.,  1.]]
    

    现在,我们希望我们的函数为每一行返回平均 1。或者换句话说,轴 1 上的平均值等于五个 1 的向量。为了实现这一点,我们创建了一个掩码矩阵其中值为零的条目被视为无效。这可以通过np.ma.masked_equal实现:

    masked = np.ma.masked_equal(matrix, 0)
    

    最后,我们在这个数组中执行 numpy 操作,系统地忽略被屏蔽的元素(0)。考虑到这一点,我们通过以下方式获得所需的结果:

    masked.mean(axis=1)
    

    这应该产生一个向量,其条目只有一个。


    更详细地说,np.ma.masked_equal(matrix, 0) 的输出应如下所示:

    masked_array(data =
     [[1.0 -- -- -- --]
     [1.0 1.0 -- -- --]
     [1.0 1.0 1.0 -- --]
     [1.0 1.0 1.0 1.0 --]
     [1.0 1.0 1.0 1.0 1.0]],
                 mask =
     [[False  True  True  True  True]
     [False False  True  True  True]
     [False False False  True  True]
     [False False False False  True]
     [False False False False False]],
           fill_value = 0.0)
    

    这表明-- 上的eh 值被视为无效。这在掩码数组的掩码属性中也显示为 True ,表示它是无效元素,因此应忽略。

    最后对这个数组进行均值运算的输出应该是:

    masked_array(data = [1.0 1.0 1.0 1.0 1.0],
                 mask = [False False False False False],
           fill_value = 1e+20)
    

    【讨论】:

    • 非常清晰的解释和非常简单的例子。 .. 谢谢!
    猜你喜欢
    • 2017-05-26
    • 2016-09-28
    • 2015-09-29
    • 2011-06-12
    • 1970-01-01
    • 2014-12-24
    • 1970-01-01
    • 2013-08-02
    相关资源
    最近更新 更多