对2D numpy数组进行均值分组

22 投票
5 回答
10734 浏览
提问于 2025-04-16 09:33

我想把一个numpy数组分成更小的部分,通过计算元素的平均值来实现。比如说,我想在一个100x100的数组中,每5x5的小块计算一次平均值,最后得到一个20x20的数组。因为我有很多数据需要处理,这样做效率高吗?

5 个回答

3

对一个二维数组进行平均值计算,分成大小为NxN的小块:

height, width = data.shape
data = average(split(average(split(data, width // N, axis=1), axis=-1), height // N, axis=1), axis=-1)
4

这其实很简单,不过我觉得可以更快一点:

from __future__ import division
import numpy as np
Norig = 100
Ndown = 20
step = Norig//Ndown
assert step == Norig/Ndown # ensure Ndown is an integer factor of Norig
x = np.arange(Norig*Norig).reshape((Norig,Norig)) #for testing
y = np.empty((Ndown,Ndown)) # for testing
for yr,xr in enumerate(np.arange(0,Norig,step)):
    for yc,xc in enumerate(np.arange(0,Norig,step)):
        y[yr,yc] = np.mean(x[xr:xr+step,xc:xc+step])

你可能还会对 scipy.signal.decimate 感兴趣。这个方法在对数据进行降采样之前,会使用比简单平均更复杂的低通滤波器,虽然你需要先对一个方向进行降采样,然后再对另一个方向进行降采样。

33

我试过在较小的数组上这样做,所以你可以用你的数组来测试一下:

import numpy as np

nbig = 100
nsmall = 20
big = np.arange(nbig * nbig).reshape([nbig, nbig]) # 100x100

small = big.reshape([nsmall, nbig//nsmall, nsmall, nbig//nsmall]).mean(3).mean(1)

这是一个6x6的例子,变成了3x3:

nbig = 6
nsmall = 3
big = np.arange(36).reshape([6,6])
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],
       [24, 25, 26, 27, 28, 29],
       [30, 31, 32, 33, 34, 35]])

small = big.reshape([nsmall, nbig//nsmall, nsmall, nbig//nsmall]).mean(3).mean(1)

array([[  3.5,   5.5,   7.5],
       [ 15.5,  17.5,  19.5],
       [ 27.5,  29.5,  31.5]])

撰写回答