2011-01-07 52 views
15

numpy配列を要素の平均値をとるように小さなサイズにグループ化しようとしています。たとえば、20×20サイズのアレイを作成するために、100×100アレイ内の5×5のサブアレイを平均して取るなど。私は巨大なデータを操作する必要があるので、それを効率的に行う方法はありますか?2D numpy配列を平均でグループ化する

+0

(https://stackoverflow.com/questions/18645013/windowed-maximum-in-numpy/18645174#18645174)も答えます。 – Daniel

答えて

23

Iは小さいアレイのためにこれを試みたので、あなたとそれをテストした:6×6と

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) 

例 - > 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]]) 
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面白いかもしれません。データをダウンサンプリングする前に、単純な平均化よりも高度なローパス・フィルタを適用しますが、一方の軸をデシメートし、次にもう一方の軸をデシメートする必要があります。

2

平均サイズN×N個のサブアレイ上に2次元アレイ。

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

いいです!平均と分裂が数え切れないほどの機能であることをはっきりと説明します。 – MonkeyButter

0

eumiro's approach.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) 
関連する問題