2016-06-15 10 views
1

私は標準の2次元配列を持っているとしましょう、値を持つmy2darrayと呼んでみましょう。この配列には2つの主要なセクションがあります。各列に「シナリオ1」と「シナリオ2」を分ける特定の行があるとします。 my2darrayの上部セクションとmy2darrayの下部を表す2つのマスクされた配列を作成するにはどうすればよいですか?たとえば、上半分の平均と下半分の平均を計算することに興味があります。 1つのアイデアは、my2darrayと同じ形状のマスクを持つことですが、それは記憶の浪費のようです。良いアイデアはありますか?私はnumpyの1.5.02次元配列のセクションを区切るベクトルでマスクされた配列を作成する方法は?

でのpython 2.6を使用していますつまり、私は

myvector=np.array([9, 15, 5,7,11,11]) 

を持っている、のは、私は長さが(この場合は6)my2darrayの行数に等しくなるベクトルを、持っているとしましょう

sample matrix

答えて

0

NumPy's broadcasted comparisonを使用して、このような2Dマスクをベクトル化して作成することができます。作品の残りの部分はすべて、np.einsumから援助を得ることができる最初の軸に沿ったsum-reductionです。結果を検証するためのサンプル実行

N = my2darray.shape[0] 
mask = myvector <= np.arange(N)[:,None] 
uout = np.true_divide(np.einsum('ij,ij->j',my2darray,~mask),myvector) 
lout = np.true_divide(np.einsum('ij,ij->j',my2darray,mask),N-myvector) 

- -

In [184]: N = my2darray.shape[0] 
    ...: mask = myvector <= np.arange(N)[:,None] 
    ...: uout = np.true_divide(np.einsum('ij,ij->j',my2darray,~mask),myvector) 
    ...: lout = np.true_divide(np.einsum('ij,ij->j',my2darray,mask),N-myvector) 
    ...: 

In [185]: uout 
Out[185]: array([ 6. , 4.6, 4. , 0. ]) 

In [186]: [my2darray[:item,i].mean() for i,item in enumerate(myvector)] 
Out[186]: [6.0, 4.5999999999999996, 4.0, 0.0] # Loopy version results 

In [187]: lout 
Out[187]: array([ 5.2  , 4.  , 2.66666667, 2.  ]) 

In [188]: [my2darray[item:,i].mean() for i,item in enumerate(myvector)] 
Out[188]: [5.2000000000000002, 4.0, 2.6666666666666665, 2.0] # Loopy version 

別の潜在的により高速な方法は、それを保存し、上層マスクの総和を計算することであろうこのように、我々はそうのような実装を持っているでしょうそこから、入力配列2Dの全長に沿った第1の軸に沿った合計を引く。これは、下位平均の計算に使用することができます。したがって、Nを保存してmaskを計算した後、 -

usum = np.einsum('ij,ij->j',my2darray,~mask) 
uout = np.true_divide(usums,myvector) 
lout = np.true_divide(my2darray.sum(0) - usums,N-myvector)