まとめ
ビンの区切り値が ndarray: bin_edges
に昇順で入っているとき、値 x
がどのビンに入るかは
get_bin_idx.py
bin_idx = np.where((bin_edges[:-1] <= x) & (x < bin_edges[1:]))[0][0]
で得られる。
追記(2016/03/16):
get_bin_idx2.py
bin_idx = np.searchsorted(bin_edges, x) - 1
でも同様なことができる (thanks to termoshtt)。
追記(2017/01/02):
さらに
get_bin_idx3.py
bin_idx = np.digitize(x, bin_edges) - 1
でも同様なことができる。
実際、Numpyのドキュメントによると、np.digitize()
の実装はnp.searchsorted()
そのものらしい。
これらの違いは単に、np.digitize(x, bin_edges)
では「x
の各要素ををbin_edges
で定義されるビンに振り分けたときのビンのインデックスを求める」という用途が想定されている一方、np.searchsorted(y, x)
では「ソート済みの配列y
にx
の各要素を挿入する際のインデックスを求める」という用途が想定されている、というだけのようだ。
例
適当なビンを乱数で作る
gen_bins.py
bin_edges = np.hstack(([0., 1.], np.random.rand(9)))
bin_edges.sort()
0 < x < 1 の値とビンの関係を図示すると
plot_bins.py
plt.step(bin_edges, np.arange(len(bin_edges)), where='post')
plt.ylim(-0.5, 9.5)
plt.xlabel('x')
plt.ylabel('Bin index')
適当な x に対して、どのビンに入るかを知るには
get_and_plot_bin_idx.py
x = np.random.rand()
bin_idx = np.where((bin_edges[:-1] <= x) & (x < bin_edges[1:]))[0][0]
plt.axvline(x, c='r')
plt.axhline(bin_idx, c='r')
もう一度、別の x で
get_and_plot_bin_idx_again.py
x = np.random.rand()
bin_idx = np.where((bin_edges[:-1] <= x) & (x < bin_edges[1:]))[0][0]
plt.axvline(x, c='g')
plt.axhline(bin_idx, c='g')
以上。