Группировка двумерных массивов в среднем - PullRequest
19 голосов
/ 07 января 2011

Я пытаюсь сгруппировать массив numy в меньший размер, взяв среднее из элементов. Например, взять среднее значение foreach 5x5 в массиве 100x100 для создания массива размером 20x20. Поскольку мне нужно манипулировать огромными данными, это эффективный способ сделать это?

Ответы [ 4 ]

26 голосов
/ 07 января 2011

Я пробовал это для меньшего массива, поэтому протестируйте его с вашим:

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]])
4 голосов
/ 07 января 2011

Это довольно просто, хотя я чувствую, что это может быть быстрее:

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 Он применяет более сложный фильтр нижних частот, чем простое усреднение, перед понижением дискретизации данных, хотя вам придется децитировать одну ось, а затем другую.

2 голосов
/ 13 мая 2011

Среднее значение для двумерного массива по подмассивам размером NxN:

height, width = data.shape
data = average(split(average(split(data, width // N, axis=1), axis=-1), height // N, axis=1), axis=-1)
0 голосов
/ 08 декабря 2016

Обратите внимание, что подход eumiro не работает для замаскированных массивов, поскольку .mean(3).mean(1) предполагает, что каждое среднее значение по оси 3 было вычислено из того же числа значений. Если в вашем массиве есть маскированные элементы, это предположение больше не выполняется. В этом случае вы должны отслеживать количество значений, используемых для вычисления .mean(3), и заменить .mean(1) на взвешенное среднее. Веса - это нормализованное число значений, используемых для вычисления .mean(3).

Вот пример:

import numpy as np


def gridbox_mean_masked(data, Nbig, Nsmall):
    # Reshape data
    rshp = data.reshape([Nsmall, Nbig//Nsmall, Nsmall, Nbig//Nsmall])

    # Compute mean along axis 3 and remember the number of values each mean
    # was computed from
    mean3 = rshp.mean(3)
    count3 = rshp.count(3)

    # Compute weighted mean along axis 1
    mean1 = (count3*mean3).sum(1)/count3.sum(1)
    return mean1


# Define test data
big = np.ma.array([[1, 1, 2],
                   [1, 1, 1],
                   [1, 1, 1]])
big.mask = [[0, 0, 0],
            [0, 0, 1],
            [0, 0, 0]]
Nbig = 3
Nsmall = 1

# Compute gridbox mean
print gridbox_mean_masked(big, Nbig, Nsmall)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...