2017-12-13 3 views
1

numpy.bincountsのナンシー最適化バージョンを作成しようとしています。私はbincountsが1対1ではないことを理解していますので、最も単純なバージョンについてお話しましょう。numpy.bincountsの逆?

import numpy as np 


def bincounts_inverse(counts): 
    list = [] 
    dtype = np.min_scalar_type(counts.shape[0] - 1) 
    for bin, count in enumerate(counts): 
     ar = np.empty(count, dtype=dtype) 
     ar[:] = bin 
     list.append(ar) 

    return np.concatenate(list) 

これは、NumpyとPythonの現在の知識で得ることができる最高のものです。カウントが高く、ビンが低いが、反対の場合は遅くなると非常に高速になります。それは漸近的に最適ですが、おそらくあなたができる最高のものではありません。

これを行うより速い方法がありますか?

ここにサンプルの入出力があります。

np.repeat(np.arange(len(counts)), counts) 

サンプル実行 - - bincount

counts = np.array([3, 1, 0, 2, 5], np.uint8) 
bincounts_inverse(counts) = np.array([0, 0, 0, 1, 3, 3, 4, 4, 4, 4, 4], 
            dtype=np.uint8) 
+1

いくつかのサンプル入力と期待される出力を提供できますか?それは助けるだろう。 –

+0

@cᴏʟᴅsmy私はそれを私の答えに追加します、ありがとう。 –

答えて

3

逆はrepeatだろう

In [22]: counts = np.array([3,0,2,1,0,2]) 

In [23]: list = [] 
    ...: dtype = np.min_scalar_type(counts.shape[0] - 1) 
    ...: for bin, count in enumerate(counts): 
    ...:  ar = np.empty(count, dtype=dtype) 
    ...:  ar[:] = bin 
    ...:  list.append(ar) 
    ...: out = np.concatenate(list) 

In [24]: out 
Out[24]: array([0, 0, 0, 2, 2, 3, 5, 5], dtype=uint8) 

In [25]: np.repeat(np.arange(len(counts)), counts) 
Out[25]: array([0, 0, 0, 2, 2, 3, 5, 5]) 

別の非ゼロインデックスを使用して、これはsparseycountsと、より効率的かもしれないと -

idx = np.flatnonzero(counts!=0) 
out = np.repeat(idx, counts[idx])