У меня есть массив данных с набором фигур (100,10). Каждая строка представляет собой горячую кодировку. Я хочу перевести его в nd-массив с формой (100,), чтобы я перенес каждую строку вектора в целое число, обозначающее индекс ненулевого индекса. Есть ли быстрый способ сделать это, используя NumPy или TenorFlow?
Как конвертировать одноразовые кодировки в целые числа?
Ответ 1
Как указал Фрэнк Демонкур (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
, что больше, чем вы просили.
Для любой конкретной строки вы просто хотите проиндексировать в. Например, в нулевой строке 1 находится в индексе 1.
>>> np.where(a[0]==1)[0][0]
1
Ответ 2
Вы можете использовать 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]
Вы также можете посмотреть на sklearn.preprocessing.LabelBinarizer.inverse_transform
.
Ответ 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]
Ответ 4
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
Ответ 5
Вы можете использовать этот простой код:
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
Ответ 6
В этих случаях я делаю что-то вроде этого. Идея состоит в том, чтобы интерпретировать вектор с одним горячим индексом как индекс массива 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
и другие предлагаемые решения могут быть медленнее, чем индексация (хотя индексация может потреблять больше памяти)