Numpy计算2D数组中行和列的子范围的平均值



Hei我正在尝试计算行和列的平均值

Ex我有阵列

a = np.array([
[1,2,3,4,5,6,7,8],
[2,3,6,1,7,4,3,6],
[6,3,5,8,9,2,6,8],
[6,2,5,8,9,3,2,7],
[5,7,3,4,7,8,5,3],
[7,3,4,5,7,4,5,6],
[5,3,7,6,7,8,4,2],
[5,4,7,7,2,1,6,4]])

我想计算第一行[1,2]和第二行[2,3]的平均值。平均值为2.0然后我想计算第一行[3,4]和第二行[6,1]的平均值。等等

结果被放置到一个大小为其一半的新数组中。

我有以下代码可以做到这一点,

完整的代码是

import numpy as np
import sys
a = np.array([
[1,2,3,4,5,6,7,8],
[2,3,6,1,7,4,3,6],
[6,3,5,8,9,2,6,8],
[6,2,5,8,9,3,2,7],
[5,7,3,4,7,8,5,3],
[7,3,4,5,7,4,5,6],
[5,3,7,6,7,8,4,2],
[5,4,7,7,2,1,6,4]])
ni = nj = 2
dim_i = a.shape[0]
dim_j = a.shape[1]
b = np.empty((int(a.shape[0]/ni), int(a.shape[1]/nj)))
for ii, i in enumerate(range(0, dim_i, ni)):
for jj, j in enumerate(range(0, dim_j, nj)):
flat = np.array([a[i][j:j+ni], a[i+1][j:j+ni]]).flatten()
b[ii,jj] = np.mean(flat)
print(b)
[[2.   3.5  5.5  6.  ]
[4.25 6.5  5.75 5.75]
[5.5  4.   6.5  4.75]
[4.25 6.75 4.5  4.  ]]

我正在寻找一种更快、更优雅的方式。因为真实数据在每个维度上都有几百或更多的大小。

这可能吗?

Mvh,Birgir。

您可以利用numpystride_ticks模块将阵列重塑为块形状。一种解决方案:

from numpy.lib.stride_tricks import as_strided
as_strided(a, shape=(4, 4, 2, 2), strides=(128, 16, 64, 8)).mean(axis=(2,3))

输出:

array([[2.  , 3.5 , 5.5 , 6.  ],
[4.25, 6.5 , 5.75, 5.75],
[5.5 , 4.  , 6.5 , 4.75],
[4.25, 6.75, 4.5 , 4.  ]])

注意,我明确定义了形状步长,但它们可以很容易地推断出来(对于2*2平均池的一般情况(

strides = tuple(map(lambda x: x*2, a.strides)) + a.strides
shape = tuple(map(lambda x: int(x / 2), a.shape)) + (2, 2)

该技巧的性能比天真环路快10倍

%%timeit
as_strided(a, shape=(4, 4, 2, 2), strides=(128, 16, 64, 8)).mean(axis=(2,3))
11.5 µs ± 44.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%%timeit
ni = nj = 2
dim_i = a.shape[0]
dim_j = a.shape[1]
b = np.empty((int(a.shape[0]/ni), int(a.shape[1]/nj)))
for ii, i in enumerate(range(0, dim_i, ni)):
for jj, j in enumerate(range(0, dim_j, nj)):
flat = np.array([a[i][j:j+ni], a[i+1][j:j+ni]]).flatten()
b[ii,jj] = np.mean(flat)
128 µs ± 1.38 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

对于较大的阵列(X200用于1000*1000阵列(,增益更显著

相关内容

  • 没有找到相关文章