取列表的平均值而不考虑零值

时间:2018-10-25 15:59:34

标签: python arrays python-3.x numpy mean

我想通过忽略每一列中的零值来为每一列取平均值。
数组是:

array([[ 12.,  26.,   0.,   0.,   0.,   0.,   0.,   0.],
       [ 12.,  27.,  36.,  46.,  56.,  66.,   0.,   0.],
       [ 13.,  22.,  38.,  50.,  66.,  81.,  94., 107.],
       [  3.,   0.,   0.,   0.,   0.,   0.,   0.,   0.]])

结果将是:

[10,25,37,48,61,73.5,94,107]

谢谢!

3 个答案:

答案 0 :(得分:1)

这里有一个NumPy数组,因此请使用NumPy。一种方法是将0的值转换为NaN,然后使用np.nanmean

A = np.array([[ 12.,  26.,   0.,   0.,   0.,   0.,   0.,   0.],
              [ 12.,  27.,  36.,  46.,  56.,  66.,   0.,   0.],
              [ 13.,  22.,  38.,  50.,  66.,  81.,  94., 107.],
              [  3.,   0.,   0.,   0.,   0.,   0.,   0.,   0.]])

B = A.copy()
B[B == 0] = np.nan
res = np.nanmean(B, axis=0)

print(res)

array([  10. ,   25. ,   37. ,   48. ,   61. ,   73.5,   94. ,  107. ])

或通过np.ma.masked_where使用掩码数组:

import numpy.ma as ma

res = np.nanmean(ma.masked_where(A == 0, A), axis=0).data

答案 1 :(得分:1)

您可以使用numpy.true_divide将数组的总和除以非零元素的数量,这相当有效:

np.true_divide(A.sum(0), (A != 0).sum(0))

array([ 10. ,  25. ,  37. ,  48. ,  61. ,  73.5,  94. , 107. ])

性能

A = np.random.randint(0, 10, (10000, 10000)).astype(float)

In [71]: %timeit np_nanmean(A)
1.73 s ± 3.48 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [72]: %timeit np_masked_nanmean(A)
1.93 s ± 7.42 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [73]: %timeit np_true_divide(A)
319 ms ± 5.61 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

答案 2 :(得分:0)

lst = [[ 12.,  26.,   0.,   0.,   0.,   0.,   0.,   0.],
   [ 12.,  27.,  36.,  46.,  56.,  66.,   0.,   0.],
   [ 13.,  22.,  38.,  50.,  66.,  81.,  94., 107.],
   [  3.,   0.,   0.,   0.,   0.,   0.,   0.,   0.]]
result_lst = map(lambda x:sum(x)/len(x),[tup if 0.0 not in tup else filter(lambda x: x != 0.0,tup) for tup in map(list,zip(*lst))])
print result_lst
Result : [10.0, 25.0, 37.0, 48.0, 61.0, 73.5, 94.0, 107.0]

嗨,我知道我们可以通过很多方式来获得输出,但是我不想使用任何Modules(numpy),我只想使用列表压缩来获得我们的结果。 让我解释一下我如何做到这一点:

  1. map(list,zip(*lst))将给出列表列表以比较基于索引的
  2. filter函数将给出不带零的列表
  3. 最后我们找到平均值

指导我是否可以对列表压缩进行有效更改