シェイプ(100,10)のnumpy配列データセットがあります。各行はワンホットエンコーディングです。各ベクトル行を非ゼロインデックスのインデックスを示す整数に転送するように、形状(100)を持つnd-arrayに転送します。 numpyまたはtensorflowを使用してこれを行う簡単な方法はありますか?
Frank Demoncourtが指摘したように、one_hotには1だけがあり、残りはゼロなので、この特定の例ではargmaxを使用できます。一般に、numpy配列で値を検索する場合は、おそらく numpy.where を参照する必要があります。また、このスタック交換の質問:
配列内の何かの最初のインデックスを返すNumPy関数はありますか?
ワンホットベクトルは、すべてが0で1つの単一のベクトルであるため、次のようなことができます。
>>> import numpy as np
>>> a = np.array([[0,1,0,0],[1,0,0,0],[0,0,0,1]])
>>> [np.where(r==1)[0][0] for r in a]
[1, 0, 3]
これは、各行に1であるインデックスのリストを作成するだけです。 [0] [0]インデックスは、np.where
によって返された構造(配列を持つタプル)を捨てるだけです。
特定の行については、aにインデックスを付けるだけです。たとえば、0番目の行では、インデックス1に1が見つかります。
>>> np.where(a[0]==1)[0][0]
1
numpy.argmax または tf.argmax を使用できます。例:
import numpy as np
a = np.array([[0,1,0,0],[1,0,0,0],[0,0,0,1]])
print('np.argmax(a, axis=1): {0}'.format(np.argmax(a, axis=1)))
出力:
np.argmax(a, axis=1): [1 0 3]
速度のためにnumpyを使用することを強くお勧めしますが、 mpu.ml.one_hot2indices(one_hots)
はnumpyなしでそれを行う方法を示しています。単にpip install mpu --user --upgrade
。
その後、あなたはできる
>>> one_hot2indices([[1, 0], [1, 0], [0, 1]])
[0, 0, 1]
def int_to_onehot(n, n_classes):
v = [0] * n_classes
v[n] = 1
return v
def onehot_to_int(v):
return v.index(1)
>>> v = int_to_onehot(2, 5)
>>> v
[0, 0, 1, 0, 0]
>>> i = onehot_to_int(v)
>>> i
2
次の簡単なコードを使用できます。
a=[[0,0,0,0,0,1,0,0,0,0]]
j=0
for i in a[0]:
if i==1:
print(j)
else:
j+=1
5
これらの場合に私がすることはこのようなものです。アイデアは、ワンホットベクトルを1,2,3,4,5 ...配列のインデックスとして解釈することです。
# Define stuff
import numpy as np
one_hots = np.zeros([100,10])
for k in range(100):
one_hots[k,:] = np.random.permutation([1,0,0,0,0,0,0,0,0,0])
# Finally, the trick
ramp = np.tile(np.arange(0,10),[100,1])
integers = ramp[one_hots==1].ravel()
私はnp.argmax
およびその他の推奨される解決策は、インデックス作成よりも遅い場合があります(ただし、インデックス作成により多くのメモリが消費される場合があります)