Подтвердить что ты не робот

Одно горячее кодирование с использованием numpy

Если вход равен нулю, я хочу создать массив, который выглядит так:

[1,0,0,0,0,0,0,0,0,0]

и если вход 5:

[0,0,0,0,0,1,0,0,0,0]

Для вышеизложенного я написал:

np.put(np.zeros(10),5,1)

но это не сработало.

Есть ли способ, который может быть реализован в одной строке?

4b9b3361

Ответ 1

Обычно, когда вы хотите получить горячую кодировку для классификации в машинное обучение, у вас есть массив индексов.

import numpy as np
nb_classes = 6
targets = np.array([[2, 3, 4, 0]]).reshape(-1)
one_hot_targets = np.eye(nb_classes)[targets]

Теперь one_hot_targets

array([[[ 0.,  0.,  1.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  1.,  0.,  0.],
        [ 0.,  0.,  0.,  0.,  1.,  0.],
        [ 1.,  0.,  0.,  0.,  0.,  0.]]])

.reshape(-1) должен быть уверен, что у вас есть правильный формат меток (у вас также может быть [[2], [3], [4], [0]]). -1 - особое значение, которое означает "положить все остальное в этом измерении". Поскольку есть только один, он выравнивает массив.

Решение для копирования-вставки

def get_one_hot(targets, nb_classes):
    return np.eye(nb_classes)[np.array(targets).reshape(-1)]

Ответ 2

Что-то вроде:

np.array([int(i == 5) for i in range(10)])

Должен сделать трюк. Но я полагаю, что существуют другие решения, использующие numpy.

edit: причина, по которой ваша формула не работает: np.put ничего не возвращает, он просто изменяет элемент, указанный в первом параметре. Хороший ответ при использовании np.put():

a = np.zeros(10)
np.put(a,5,1)

Проблема заключается в том, что она не может быть выполнена в одной строке, так как вам нужно определить массив, прежде чем передать его в np.put()

Ответ 3

Проблема заключается в том, что вы сохраняете свой массив нигде. Функция put работает на месте массива и ничего не возвращает. Поскольку вы никогда не даете вашему массиву имя, вы не можете его обработать позже. Итак, это

one_pos = 5
x = np.zeros(10)
np.put(x, one_pos, 1)

будет работать, но тогда вы можете просто использовать индексирование:

one_pos = 5
x = np.zeros(10)
x[one_pos] = 1

По моему мнению, это был бы правильный способ сделать это, если нет особых причин для этого в качестве одного лайнера. Это также может быть проще для чтения и чтения кода является хорошим кодом.

Ответ 4

np.put мутирует свой массив arg на месте. В Python он является обычным для функций/методов, которые выполняют мутацию in-place для возврата None; np.put придерживается этого соглашения. Поэтому, если a является 1D-массивом, и вы делаете

a = np.put(a, 5, 1)

то a будет заменено на None.

Ваш код аналогичен этому, но он передает неименованный массив в np.put.

Компактный и эффективный способ делать то, что вам нужно, - это простая функция, например:

import numpy as np

def one_hot(i):
    a = np.zeros(10, 'uint8')
    a[i] = 1
    return a

a = one_hot(5) 
print(a)

Выход

[0 0 0 0 0 1 0 0 0 0]

Ответ 5

Используйте np.identify или np.eye. Вы можете попробовать что-то подобное с вашим входом i, а размер массива s:

np.identify(s)[i:i+1]

Например, print(np.identity(5)[0:1]) приведет к:

[[ 1.  0.  0.  0.  0.  0.  0.  0.  0.  0.]]

Если вы используете TensorFlow, вы можете использовать tf.one_hot: https://www.tensorflow.org/api_docs/python/array_ops/slicing_and_joining#one_hot

Ответ 6

Внимательно просмотрев руководство, вы увидите, что np.put не возвращает значение. Хотя ваша техника в порядке, вы получаете доступ к None вместо массива результатов.

Для одномерного массива лучше просто использовать прямую индексацию, особенно для такого простого случая.

Вот как переписать свой код с минимальной модификацией:

arr = np.zeros(10)
np.put(arr, 5, 1)

Вот как сделать вторую строку с индексированием вместо put:

arr[5] = 1

Ответ 7

Вы можете использовать List comprehension:

[0 if i !=5 else 1 for i in range(10)]

превращается в

[0,0,0,0,0,1,0,0,0,0]

Ответ 8

import time
start_time = time.time()
z=[]
for l in [1,2,3,4,5,6,1,2,3,4,4,6,]:
    a= np.repeat(0,10)
    np.put(a,l,1)
    z.append(a)
print("--- %s seconds ---" % (time.time() - start_time))

#--- 0.00174784660339 seconds ---

import time
start_time = time.time()
z=[]
for l in [1,2,3,4,5,6,1,2,3,4,4,6,]:
    z.append(np.array([int(i == l) for i in range(10)]))
print("--- %s seconds ---" % (time.time() - start_time))

#--- 0.000400066375732 seconds ---

Ответ 9

Я не уверен, что производительность, но следующий код работает, и он опрятен.

x = np.array([0, 5])
x_onehot = np.identity(6)[x]