numpy覚書
大したことしてないけど忘れたとき用に書いておく。
(命名が微妙なのはまあ文脈によって変えるという感じで)
one_hot
def one_hot(v): return np.eye(v.shape[1], dtype=int)[np.argmax(v, axis=1)]
個の次元ベクトルに対し、それぞれのベクトルで最大の要素を他をにしたベクトルを返す。具体的には以下。
>>> v array([[0.1, 0.2, 0.7], [0.5, 0.3, 0.2], [0.3, 0.3, 0.4]]) >>> one_hot(v) array([[0, 0, 1], [1, 0, 0], [0, 0, 1]])
仕組みはnp.eye()
で単位行列を生成、np.argmax()
でv
の各ベクトルの最大値のインデックスを並べたn次元ベクトルを生成しそれを添え字とする。
count_class
def count_class(v): return np.sum(one_hot(v), axis=0)
個の次元ベクトルに対し、各インデックスごとにそのインデックスが最大値をとるベクトルの個数を現した配列を返す。
>>> v array([[0.1, 0.2, 0.7], [0.5, 0.3, 0.2], [0.3, 0.3, 0.4]]) >>> count_class(v) array([1, 0, 2])
one_hot()
してaxis=0で足すだけ。
select_classes
def select_classes(v, cls): return v[np.isin(np.argmax(v, axis=1), cls)]
個の次元ベクトルに対し、最大値のインデックスが指定したいずれかの値とマッチしているベクトルのみを返す。
>>> v array([[0.1, 0.2, 0.7], [0.5, 0.3, 0.2], [0.3, 0.3, 0.4]]) >>> select_classes(v, [0, 1]) array([[0.5, 0.3, 0.2]]) >>> select_classes(v, [1, 2]) array([[0.1, 0.2, 0.7], [0.3, 0.3, 0.4]])
np.isin()
でv
の最大値のインデックスがcls
に含まれているか否かの真偽値ベクトルを生成し添え字に利用。
ちなみにnp.isin()
はnumpyのversion 1.13.0 から入ったらしく、これが無いときは以下のようにしてた。
def select_classes(v, cls): ind = np.zeros(v.shape[0], dtype=bool) v_cls = np.argmax(v, axis=1) for c in cls: ind |= (v_cls == c) return v[ind]
おまけ
pythonのインタラクティブシェル便利だけど、毎回import numpy
するのめんどうなので以下のようにしておくとコマンドラインでnumpy
と打てばnumpyをインポートした状態でインタラクティブシェルを始められる。
$ echo "import numpy as np" > ${HOME}/.startup_numpy.py $ alias numpy="PYTHONSTARTUP=${HOME}/.startup_numpy.py python"