2016-11-30 4 views
2

私はN個の要素の配列(ソートされていない)を持っています。私はNの元の順序を維持したいと思いますが、実際の要素の代わりに、Nにはビン番号を持たせたいと思います。ここでNはmビンに等しく分割されます(Nがmで割り切れる場合) (Nで割り切れないN)値。私はベクトル化された解を必要とします(Nはかなり大きいので、標準的なPythonの方法は効率的ではありません)。これを行うことができるscipyまたはnumpyに何かがありますか?配列を等号のビンに分割する

e.g. 
N = [0.2, 1.5, 0.3, 1.7, 0.5] 
m = 2 
Desired output: [0, 1, 0, 1, 0] 

私はnumpy.histogramを見ましたが、不等間隔のビンを与えません。この記事に記載されている

答えて

1

np.searchsorted用いて入力配列の長さのために等間隔のインデックスを作成するという考えとnumpyのベースベクトル化手法である - ここ実装の -

def equal_bin(N, m): 
    sep = (N.size/float(m))*np.arange(1,m+1) 
    idx = sep.searchsorted(np.arange(N.size)) 
    return idx[N.argsort().argsort()] 

サンプルビンカウントで実行され各ビンは、結果を検証するために -

In [442]: N = np.arange(1,94) 

In [443]: np.bincount(equal_bin(N, 4)) 
Out[443]: array([24, 23, 23, 23]) 

In [444]: np.bincount(equal_bin(N, 5)) 
Out[444]: array([19, 19, 18, 19, 18]) 

In [445]: np.bincount(equal_bin(N, 10)) 
Out[445]: array([10, 9, 9, 10, 9, 9, 10, 9, 9, 9]) 

をここでlinspaceを使用して、別のアプローチがありますインデックスとして使用することができるもの等間隔の数字を作成するために、そうのよう -

def equal_bin_v2(N, m): 
    idx = np.linspace(0,m,N.size+0.5, endpoint=0).astype(int) 
    return idx[N.argsort().argsort()] 

サンプルラン -

In [689]: N 
Out[689]: array([ 0.2, 1.5, 0.3, 1.7, 0.5]) 

In [690]: equal_bin_v2(N,2) 
Out[690]: array([0, 1, 0, 1, 0]) 

In [691]: equal_bin_v2(N,3) 
Out[691]: array([0, 1, 0, 2, 1]) 

In [692]: equal_bin_v2(N,4) 
Out[692]: array([0, 2, 0, 3, 1]) 

In [693]: equal_bin_v2(N,5) 
Out[693]: array([0, 3, 1, 4, 2]) 
+0

Iはnp.arange(1,94)= Nのためにこれを実行し、M = 10ビニングはほぼ同じサイズではありませんでした。私はそれが主に9または10であると思っていますが、6要素のビンと11ビンのビンがあります。 –

+0

@max_max_mirアップデートされたバージョンをチェックしてください。 – Divakar

+0

@Divakarというクイックレスポンスに感謝します。最初のものはまだまだそこにはまだありません(それは近いです)。 equal_bin(np.arange(1,91)、10)を試してみると、8個のビンに9個の要素がありますが、1個のビンに10個、もう1個に8個あります。この場合、それぞれに9つの要素が必要です。 –