Una encoding en caliente usando numpy

Si la entrada es cero, quiero hacer una matriz que se vea así:

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

y si la entrada es 5:

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

Por lo anterior escribí:

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

Pero no funcionó.

¿Hay alguna forma en que, esto se puede implementar en una línea?

    Por lo general, cuando desea obtener una encoding única para la clasificación en aprendizaje automático, tiene una serie de índices.

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

    El one_hot_targets es ahora

     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.]]]) 

    La .reshape(-1) está ahí para asegurarse de que tiene el formato de tags correcto (también puede tener [[2], [3], [4], [0]] ). El -1 es un valor especial que significa “poner todas las cosas restantes en esta dimensión”. Como solo hay uno, aplana la matriz.

    Solución de copiar y pegar

     def get_one_hot(targets, nb_classes): res = np.eye(nb_classes)[np.array(targets).reshape(-1)] return res.reshape(list(targets.shape)+[nb_classes]) 

    Paquete

    Puedes usar mpu.ml.indices2one_hot . Es probado y simple de usar:

     import mpu.ml one_hot = mpu.ml.indices2one_hot([1, 3, 0], nb_classes=5) 

    Algo como :

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

    Debería hacer el truco. Pero supongo que existen otras soluciones usando numpy.

    edit: la razón por la que su fórmula no funciona: np.put no devuelve nada, solo modifica el elemento dado en el primer parámetro. La buena respuesta al usar np.put() es:

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

    El problema es que no se puede hacer en una línea, ya que necesita definir la matriz antes de pasarla a np.put()

    Usted podría utilizar la comprensión de la lista:

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

    se vuelve a

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

    Echando un vistazo rápido al manual , verá que np.put no devuelve un valor. Si bien su técnica está bien, está accediendo a None lugar de a su matriz de resultados.

    Para una matriz 1-D es mejor usar solo la indexación directa, especialmente para un caso tan simple.

    Aquí es cómo volver a escribir su código con una modificación mínima:

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

    Aquí es cómo hacer la segunda línea con la indexación en lugar de put :

     arr[5] = 1 

    El problema aquí es que guardas tu matriz en ninguna parte. La función put funciona en su lugar en la matriz y no devuelve nada. Como nunca le asignas un nombre a tu matriz, no podrás resolverlo más adelante. Así que esto

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

    Funcionaría, pero luego podrías usar la indexación:

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

    En mi opinión, esa sería la forma correcta de hacer esto si no existe una razón especial para hacerlo como una sola línea. Esto también podría ser más fácil de leer y el código legible es un buen código.

    El np.put muta su matriz arg en el lugar . Es convencional en Python para funciones / métodos que realizan una mutación in situ para devolver None ; np.put adhiere a esa convención. Así que si a es una matriz 1D y lo haces

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

    entonces a será reemplazado por None .

    Su código es similar a eso, pero pasa una matriz sin nombre a np.put .

    Una forma compacta y eficiente de hacer lo que quiere es con una función simple, por ejemplo:

     import numpy as np def one_hot(i): a = np.zeros(10, 'uint8') a[i] = 1 return a a = one_hot(5) print(a) 

    salida

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

    Utilice np.identity o np.eye . Puedes probar algo como esto con tu entrada i, y el tamaño de matriz s:

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

    Por ejemplo, print(np.identity(5)[0:1]) resultará:

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

    Si está utilizando TensorFlow, puede usar tf.one_hot : https://www.tensorflow.org/api_docs/python/array_ops/slicing_and_joining#one_hot

     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 --- 

    No estoy seguro del rendimiento, pero el siguiente código funciona y está limpio.

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