我有一个非常大的蒙版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)
必须有一种更优雅的方式来做到这一点。非常感谢!
答案 0 :(得分:9)
两个值a
和b
的平均值为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
。
向量m
中元素m+n
到v
的总和与从m-1
m+n
元素中减去cumsum(v)
元素相同。 除非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 :(得分:0)
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]]
答案 2 :(得分:0)
您的问题(每两行有两列的平均值):
>>> 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 列获取2D阵列 a 的 r 行的平均值的通用公式:
a.transpose().reshape(-1,r).mean(1).reshape(c,-1).transpose()