2013-02-17 17 views
11

私は、2D numpy配列の数値ビニングを行うための高速なフォーミュレーションを探しています。ビニングとは、サブマトリックスの平均値または累積値を計算することです。例えば、 x = numpy.arange(16).reshape(4,4)は、それぞれ2x2の4つの部分行列で分割され、numpy.array([[2.5.4.5]、[10.5,12.5]))を与え、2.5 = numpyとなります。平均([0,1,4,5])など...Numpy 2D配列を再分割する

このような操作を効率的に実行する方法...私は実際にどのようにこれを行うには理想を持っていません...

多くのおかげで...

+0

は、部分行列が正確に、フィットするように保証されていますか?あなたはnumpy 1.7ありますか?利用可能です(ちょうどきちんとした、必要ではない)? – seberg

+0

私はnumpy 1.8devを持っていますが、私の仕事は古いバージョンです... – user1187727

答えて

17

あなたは、アレイの高次元ビューを使用して、余分な次元に沿って平均をとることができます。

In [12]: a = np.arange(36).reshape(6, 6) 

In [13]: a 
Out[13]: 
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]]) 

In [14]: a_view = a.reshape(3, 2, 3, 2) 

In [15]: a_view.mean(axis=3).mean(axis=1) 
Out[15]: 
array([[ 3.5, 5.5, 7.5], 
     [ 15.5, 17.5, 19.5], 
     [ 27.5, 29.5, 31.5]]) 

を一般的には、シェイプ(a, b)のビンをしたい場合は(rows, cols)の配列のために、それのあなたの整形を.reshape(rows // a, a, cols // b, b)である必要があります。また、.meanの順番が重要であることにも注意してください。 a_view.mean(axis=1)は3つの次元しか持たないので、a_view.mean(axis=1).mean(axis=2)は正常に動作しますが、何が起きているのかを理解するのが難しくなります。a_view.mean(axis=1).mean(axis=3)はエラーを発生させます。

としてはarowsを分割しbcolsを分割した場合、あなたの配列、すなわち内部のビンの整数を収めることができた場合、上記のコードは唯一の作品です。他のケースに対処する方法はありますが、その場合に必要な動作を定義する必要があります。

+4

on numpy 1.7。それを '.mean(axis =(1,3))'にまとめることができます! – seberg

+1

私はこの再構成が可能であることを知りませんでした。不幸にも、平均は従属的に並べられているので、平均をどのようにして得るか。あなたの例で2,2のサブマトリックス(私はコーナー0,1,6,7などを意味する...)? – user1187727

+1

@ user1187727私はあなたの質問を理解しているとは思わないが、 '[[0、1]、[6,7]]の平均は' a_view.mean(axis = 3).mean(軸= 1) '。 – Jaime

0

私はあなただけで、一般的によく機能し、ちょうどあなたの例ではnumpy.reshapeのように、アレイと何かをする機能を構築する方法を知りたいと仮定します。したがって、パフォーマンスが重要で、すでにnumpyを使用している場合は、numpyのように独自のCコードを記述できます。たとえば、arangeの実装は完全にCです。パフォーマンスに関して重要なnumpyのほとんどすべてがC言語で実装されています。

しかし、そうする前に、コードをPythonで実装して、十分です。できるだけ効率的なpythonコードを作成してみてください。まだあなたのパフォーマンスのニーズに合っていない場合は、Cの方法に進みます。

これはdocsで読むことができます。

1

はこのスニペットを提供the SciPy Cookbook on rebinningを参照してください。

def rebin(a, *args): 
    '''rebin ndarray data into a smaller ndarray of the same rank whose dimensions 
    are factors of the original dimensions. eg. An array with 6 columns and 4 rows 
    can be reduced to have 6,3,2 or 1 columns and 4,2 or 1 rows. 
    example usages: 
    >>> a=rand(6,4); b=rebin(a,3,2) 
    >>> a=rand(6); b=rebin(a,2) 
    ''' 
    shape = a.shape 
    lenShape = len(shape) 
    factor = asarray(shape)/asarray(args) 
    evList = ['a.reshape('] + \ 
      ['args[%d],factor[%d],'%(i,i) for i in range(lenShape)] + \ 
      [')'] + ['.sum(%d)'%(i+1) for i in range(lenShape)] + \ 
      ['/factor[%d]'%i for i in range(lenShape)] 
    print ''.join(evList) 
    return eval(''.join(evList)) 
関連する問題