Группировка массива 2D numpy в среднем

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

  • Python: получить escape-строку SQL
  • Не удалось «импортировать matplotlib.pyplot как plt» в virtualenv
  • Postgres: INSERT, если не существует
  • Вызов функций с несколькими аргументами при использовании Groupby
  • Транспонирование матрицы в Python
  • Упорядоченные наборы Python 2.7
  • Какой способ пойти с перекрученным и веб-программированием?
  • RuntimeError: основной поток не находится в основном цикле
  • 4 Solutions collect form web for “Группировка массива 2D numpy в среднем”

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

    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) 

    Пример с 6×6 -> 3×3:

     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]]) 

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

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

    Средний 2D-массив по подмассивам размером NxN:

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

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