【问题标题】:Fast way to take average of every N rows in a .npy array获取 .numpy 数组中每 N 行平均值的快速方法
【发布时间】:2015-08-03 10:48:14
【问题描述】:

我有一个非常大的掩码 NumPy 数组 (originalArray),其中包含许多行和两列。我想取originalArray 中每两行的平均值并构建一个newArray,其中每一行是originalArray 中两行的平均值(所以newArray 的行数是originalArray 的一半)。这应该是一件简单的事情,但下面的脚本非常慢。社区的任何建议将不胜感激。

newList = []
for i in range(0, originalArray.shape[0], 2):
    r = originalArray[i:i+2,:].mean(axis=0)
    newList.append(r)
newArray = np.asarray(newList)

必须有更优雅的方式来做到这一点。非常感谢!

【问题讨论】:

标签: python numpy


【解决方案1】:

ab 两个值的平均值是 0.5*(a+b)
因此,您可以这样做:

newArray = 0.5*(originalArray[0::2] + originalArray[1::2])

它将所有连续的两行相加,最后将每个元素乘以0.5

由于您在标题中要求 N 行的平均值,因此这是一个更通用的解决方案:

def groupedAvg(myArray, N=2):
    result = np.cumsum(myArray, 0)[N-1::N]/float(N)
    result[1:] = result[1:] - result[:-1]
    return result

n 元素的平均值的一般形式是 sum([x1,x2,...,xn])/n。 向量v 中元素mm+n 的总和与从cumsum(v)m+nth 元素中减去m-1th 元素相同。 除非m 为 0,否则在这种情况下你不会减去任何东西(结果 [0])。
这就是我们在这里利用的优势。此外,由于一切都是线性的,我们在哪里除以 N 并不重要,所以我们一开始就这样做,但这只是个人喜好问题。

如果最后一组的元素少于N,它将被完全忽略。 如果不想忽略,就得对最后一组特殊对待:

def avg(myArray, N=2):
    cum = np.cumsum(myArray,0)
    result = cum[N-1::N]/float(N)
    result[1:] = result[1:] - result[:-1]

    remainder = myArray.shape[0] % N
    if remainder != 0:
        if remainder < myArray.shape[0]:
            lastAvg = (cum[-1]-cum[-1-remainder])/float(remainder)
        else:
            lastAvg = cum[-1]/float(remainder)
        result = np.vstack([result, lastAvg])

    return result

【讨论】:

  • 我认为您应该删除中间的-1。它正在跳过最后一行。
  • 非常聪明的算法!尽管在尝试对简单的一维数组进行平均时,它给出了错误的答案,例如[1,2,3,4,5,6,7]。问题是 result[1:] -= result[:-1] 行。如果您将其更改为: result[1:] = result[1:] - result[:-1] 它可以完美运行。看起来这两者是等价的,但正如我 found out 一样,它们之间有一个至关重要的区别
  • @iasonas 你是对的,这是一个非常严重的问题,对于二维数组也是如此......我会改变它,谢谢! :)
【解决方案2】:

您的问题(每两行两列的平均值):

>>> a = np.reshape(np.arange(12),(6,2))
>>> a
array([[ 0,  1],
       [ 2,  3],
       [ 4,  5],
       [ 6,  7],
       [ 8,  9],
       [10, 11]])
>>> a.transpose().reshape(-1,2).mean(1).reshape(2,-1).transpose()
array([[  1.,   2.],
       [  5.,   6.],
       [  9.,  10.]])

其他维度(每四行三列的平均值):

>>> a = np.reshape(np.arange(24),(8,3))
>>> a
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11],
       [12, 13, 14],
       [15, 16, 17],
       [18, 19, 20],
       [21, 22, 23]])
>>> a.transpose().reshape(-1,4).mean(1).reshape(3,-1).transpose()
array([[  4.5,   5.5,   6.5],
       [ 16.5,  17.5,  18.5]])

对具有 c 列的二维数组 ar 行平均值的一般公式:

a.transpose().reshape(-1,r).mean(1).reshape(c,-1).transpose()

【讨论】:

  • 作为对环顾四周的其他人的说明,此答案仅在 a.shape[0] % r == 0 时有效
【解决方案3】:
import numpy as np

def av(array):
    return  1. * np.sum(array.reshape(1. * array.shape[0] / 2,2, array.shape[1]),axis = 1) / array.shape[1]

a = np.array([[1,1],[2,2],[3,3],[4,4]])

print av(a)

>> [[ 1.5  1.5] [ 3.5  3.5]]

【讨论】:

  • 谢谢,但我想到的是:a = np.array([[1,1],[2,2],[3,3],[4,4]]),结果为r = ([[1.5,1.5],[3.5,3.5]])
猜你喜欢
  • 1970-01-01
  • 2019-01-08
  • 2013-11-28
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
  • 2013-04-04
  • 1970-01-01
相关资源
最近更新 更多