【问题标题】:Calculating Mean of arrays with different lengths计算具有不同长度的数组的平均值
【发布时间】:2012-04-20 22:36:06
【问题描述】:

当多个数组的长度可能不同时,是否可以计算它们的平均值?我正在使用 numpy。所以假设我有:

numpy.array([[1, 2, 3, 4, 8],    [3, 4, 5, 6, 0]])
numpy.array([[5, 6, 7, 8, 7, 8], [7, 8, 9, 10, 11, 12]])
numpy.array([[1, 2, 3, 4],       [5, 6, 7, 8]])

现在我想计算平均值,但忽略“缺失”的元素(当然,我不能只附加零,因为这会弄乱平均值)

有没有办法在不遍历数组的情况下做到这一点?

PS。这些数组都是二维的,但该数组的坐标数量总是相同的。 IE。第一个数组是 5 和 5,第二个是 6 和 6,第三个是 4 和 4。

一个例子:

np.array([[1, 2],    [3, 4]])
np.array([[1, 2, 3], [3, 4, 5]])
np.array([[7],       [8]])

这必须给

(1+1+7)/3  (2+2)/2   3/1
(3+3+8)/3  (4+4)/2   5/1

并以图形方式:

[1, 2]    [1, 2, 3]    [7]
[3, 4]    [3, 4, 5]    [8]

现在想象一下,这些二维数组被放置在彼此的顶部,坐标重叠导致该坐标的平均值。

【问题讨论】:

  • mean() 有什么问题?我不确定我是否了解您想要什么,或者 mean() 没有为您做什么。
  • “忽略丢失的元素”仍然很模糊。您能否举一个非常简单的示例,其中包含数据以及您希望为该数据生成的值?
  • 你的问题不是很清楚。您能否说明您打算如何计算平均值以及您的预期结果是什么?
  • 如果数组长度不同,mean() 似乎不起作用
  • 我添加了一个例子来说明我的意思,我希望它可以帮助@Nolen

标签: python arrays numpy mean


【解决方案1】:

numpy.ma.mean 允许您计算非屏蔽数组元素的平均值。但是,要使用numpy.ma.mean,您必须首先将三个 numpy 数组组合成一个掩码数组:

import numpy as np
x = np.array([[1, 2], [3, 4]])
y = np.array([[1, 2, 3], [3, 4, 5]])
z = np.array([[7], [8]])

arr = np.ma.empty((2,3,3))
arr.mask = True
arr[:x.shape[0],:x.shape[1],0] = x
arr[:y.shape[0],:y.shape[1],1] = y
arr[:z.shape[0],:z.shape[1],2] = z
print(arr.mean(axis = 2))

产量

[[3.0 2.0 3.0]
 [4.66666666667 4.0 5.0]]

【讨论】:

  • 哇,谢谢,我永远不会发现!我希望有一个更简单的方法,但我想这将不得不这样做。谢谢!
【解决方案2】:

我经常需要它来绘制不同长度的性能曲线的平均值。

用简单的函数解决它(基于@unutbu 的回答):

def tolerant_mean(arrs):
    lens = [len(i) for i in arrs]
    arr = np.ma.empty((np.max(lens),len(arrs)))
    arr.mask = True
    for idx, l in enumerate(arrs):
        arr[:len(l),idx] = l
    return arr.mean(axis = -1), arr.std(axis=-1)

y, error = tolerant_mean(list_of_ys_diff_len)
ax.plot(np.arange(len(y))+1, y, color='green')

因此,将该函数应用于上面绘制的曲线列表会产生以下结果:

【讨论】:

    【解决方案3】:

    下面的函数也可以通过添加不同长度的数组列来工作:

    def avgNestedLists(nested_vals):
        """
        Averages a 2-D array and returns a 1-D array of all of the columns
        averaged together, regardless of their dimensions.
        """
        output = []
        maximum = 0
        for lst in nested_vals:
            if len(lst) > maximum:
                maximum = len(lst)
        for index in range(maximum): # Go through each index of longest list
            temp = []
            for lst in nested_vals: # Go through each list
                if index < len(lst): # If not an index error
                    temp.append(lst[index])
            output.append(np.nanmean(temp))
        return output
    

    从你的第一个例子开始:

    avgNestedLists([[1, 2, 3, 4, 8], [5, 6, 7, 8, 7, 8], [1, 2, 3, 4]])
    

    输出:

    [2.3333333333333335,
     3.3333333333333335,
     4.333333333333333,
     5.333333333333333,
     7.5,
     8.0]
    

    一开始没有使用 np.amax(nested_lst) 或 np.max(nested_lst) 来查找最大值的原因是,如果嵌套列表的大小不同,它将返回一个数组。

    【讨论】:

      【解决方案4】:

      OP,我知道您正在寻找一个非迭代的内置解决方案,但以下内容实际上只需要 3 行(如果您将 transposemeans 结合使用,则为 2 行,但它会变得混乱):

      arrays = [
          np.array([1,2], [3,4]),
          np.array([1,2,3], [3,4,5]),
          np.array([7], [8])
          ]
      
      mean = lambda x: sum(x)/float(len(x)) 
      
      transpose = [[item[i] for item in arrays] for i in range(len(arrays[0]))]
      
      means = [[mean(j[i] for j in t if i < len(j)) for i in range(len(max(t, key = len)))] for t in transpose]
      

      输出:

      >>>means
      [[3.0, 2.0, 3.0], [4.666666666666667, 4.0, 5.0]]
      

      【讨论】:

      • 谢谢,整洁优雅!我真的不需要经常计算,但会记下它以供将来参考。
      • @Casper:没问题。仅供参考,我在 CodeGolf 上发现了另一种获得数组转置的好方法。你可以用它代替我上面的那个:transpose = zip(*arrays)
      • 在 numpy 中,我倾向于只使用 np.transpose(my_array),显然您也可以使用 my_array.T - 尽管我更喜欢前者以提高可读性。
      猜你喜欢
      • 2014-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-21
      • 2013-10-25
      • 2014-05-14
      相关资源
      最近更新 更多