Как конвертировать одноразовые кодировки в целые числа?

У меня есть массив данных с набором фигур (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 и другие предлагаемые решения могут быть медленнее, чем индексация (хотя индексация может потреблять больше памяти)