Convierta una matriz de índices en una matriz codificada en caliente en NumPy

5 minutos de lectura

avatar de usuario
james atwood

Dada una matriz 1D de índices:

a = array([1, 0, 3])

Quiero codificar esto en caliente como una matriz 2D:

b = array([[0,1,0,0], [1,0,0,0], [0,0,0,1]])

avatar de usuario
YXD

tu matriz a define las columnas de los elementos distintos de cero en la matriz de salida. También debe definir las filas y luego usar una indexación elegante:

>>> a = np.array([1, 0, 3])
>>> b = np.zeros((a.size, a.max()+1))
>>> b[np.arange(a.size),a] = 1
>>> b
array([[ 0.,  1.,  0.,  0.],
       [ 1.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  1.]])

  • @JamesAtwood depende de la aplicación, pero convertiría el máximo en un parámetro y no lo calcularía a partir de los datos.

    – Mohammad Moghimi

    08/02/2016 a las 20:40

  • ¿y si ‘a’ fuera 2d? y quieres una matriz 3-d one-hot?

    – ANUNCIO

    18/10/2017 a las 22:39

  • ¿Alguien puede señalar una explicación de por qué esto funciona, pero la porción con [:, a] ¿no es?

    – N. McA.

    16 de febrero de 2018 a las 19:40

  • @ Solución AD para el caso 2d -> 3d: stackoverflow.com/questions/36960320/…

    – cgnorthcutt

    29 de septiembre de 2018 a las 2:37

  • También puede usar scipy.sparse.

    – matemáticas

    08/04/2019 a las 20:17

avatar de usuario
K3—rnc

>>> values = [1, 0, 3]
>>> n_values = np.max(values) + 1
>>> np.eye(n_values)[values]
array([[ 0.,  1.,  0.,  0.],
       [ 1.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  1.]])

  • Esta solución es la única útil para una matriz ND de entrada a una matriz N+1D one-hot. Ejemplo: input_matrix=np.asarray([[0,1,1] , [1,1,2]]); np.ojo(3)[input_matrix] # tensor 3D de salida

    – Isaías

    21 de marzo de 2017 a las 16:06


  • +1 porque esto debería preferirse a la solución aceptada. Sin embargo, para una solución más general, values debería ser una matriz Numpy en lugar de una lista de Python, entonces funciona en todas las dimensiones, no solo en 1D.

    – Alex

    21/10/2017 a las 20:32

  • Tenga en cuenta que tomando np.max(values) + 1 ya que la cantidad de cubos puede no ser deseable si su conjunto de datos se muestra aleatoriamente y, por casualidad, es posible que no contenga el valor máximo. El número de cubos debe ser más bien un parámetro y se puede establecer una afirmación/comprobación para verificar que cada valor esté dentro de 0 (incluido) y el recuento de cubos (excluido).

    – Elfik de la noche

    19 de enero de 2018 a las 3:46

  • Para mí, esta solución es la mejor y se puede generalizar fácilmente a cualquier tensor: def one_hot(x, depth=10): return np.eye(profundidad)[x]. Tenga en cuenta que dar el tensor x como índice devuelve un tensor de filas de ojos en forma de x.

    – cecconeurale

    27 de marzo de 2018 a las 7:37


  • Manera fácil de “comprender” esta solución y por qué funciona para N-dims (sin leer numpy docs): en cada ubicación en la matriz original (values), tenemos un número entero ky “ponemos” el vector 1-caliente eye(n)[k] en ese lugar. Esto agrega una dimensión porque estamos “poniendo” un vector en la ubicación de un escalar en la matriz original.

    – avivar

    24 de septiembre de 2019 a las 14:08

avatar de usuario
Jodó

En caso de que esté usando keras, hay una utilidad integrada para eso:

from keras.utils.np_utils import to_categorical   

categorical_labels = to_categorical(int_labels, num_classes=3)

Y hace más o menos lo mismo que la respuesta de @YXD (ver código fuente).

avatar de usuario
D.Samchuk

Esto es lo que encuentro útil:

def one_hot(a, num_classes):
  return np.squeeze(np.eye(num_classes)[a.reshape(-1)])

Aquí num_classes representa el número de clases que tiene. entonces si tienes a vector con forma de (10000,) esta función lo transforma en (10000,C). Tenga en cuenta que a está indexado a cero, es decir one_hot(np.array([0, 1]), 2) daré [[1, 0], [0, 1]].

Exactamente lo que querías tener, creo.

PD: la fuente es Modelos de secuencia – deeplearning.ai

avatar de usuario
Karma

También puedes usar ojo función de numpy:

numpy.eye(number of classes)[vector containing the labels]

  • Para mayor claridad usando np.identity(num_classes)[indices] podría ser mejor. ¡Buena respuesta!

    – Óliver

    2 de septiembre de 2019 a las 11:13

  • Esa es la única respuesta absolutamente pitónica en toda su brevedad.

    – Maksim Ganenko

    7 de junio de 2021 a las 9:59

  • Esto ha repetido la respuesta de K3—rnc dos años después, y nadie parece verlo.

    – questionto42standswithUkraine

    16 de julio de 2021 a las 0:15


  • Considere también remodelar el vector que contiene las etiquetas. numpy.eye(num_class)[labels.reshape(-1)]. Entonces, por ejemplo, la dimensión de las etiquetas es (x, 1), entonces no producirá la dimensión (num_class, x, 1).

    – Péter Szilvási

    22 de julio a las 12:53


avatar de usuario
franck dernoncourt

Puedes usar sklearn.preprocessing.LabelBinarizer:

Ejemplo:

import sklearn.preprocessing
a = [1,0,3]
label_binarizer = sklearn.preprocessing.LabelBinarizer()
label_binarizer.fit(range(max(a)+1))
b = label_binarizer.transform(a)
print('{0}'.format(b))

producción:

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

Entre otras cosas, puede inicializar sklearn.preprocessing.LabelBinarizer() para que la salida de transform es escaso

  • Para mayor claridad usando np.identity(num_classes)[indices] podría ser mejor. ¡Buena respuesta!

    – Óliver

    2 de septiembre de 2019 a las 11:13

  • Esa es la única respuesta absolutamente pitónica en toda su brevedad.

    – Maksim Ganenko

    7 de junio de 2021 a las 9:59

  • Esto ha repetido la respuesta de K3—rnc dos años después, y nadie parece verlo.

    – questionto42standswithUkraine

    16 de julio de 2021 a las 0:15


  • Considere también remodelar el vector que contiene las etiquetas. numpy.eye(num_class)[labels.reshape(-1)]. Entonces, por ejemplo, la dimensión de las etiquetas es (x, 1), entonces no producirá la dimensión (num_class, x, 1).

    – Péter Szilvási

    22 de julio a las 12:53


Para 1 codificación en caliente

   one_hot_encode=pandas.get_dummies(array)

Por ejemplo

DISFRUTA DE LA CODIFICACIÓN

  • Gracias por el comentario, pero una breve descripción de lo que hace el código sería muy útil.

    – Claro

    10 de abril de 2020 a las 23:33

  • por favor refiérase al ejemplo

    – Shubham Mishra

    10 de abril de 2020 a las 23:47

  • @Clarus Consulte el siguiente ejemplo. Puede acceder a la codificación en caliente de cada valor en su matriz np haciendo un one_hot_encode[value]. >>> import numpy as np >>> import pandas >>> a = np.array([1,0,3]) >>> one_hot_encode=pandas.get_dummies(a) >>> print(one_hot_encode) 0 1 3 0 0 1 0 1 1 0 0 2 0 0 1 >>> print(one_hot_encode[1]) 0 1 1 0 2 0 Name: 1, dtype: uint8 >>> print(one_hot_encode[0]) 0 0 1 1 2 0 Name: 0, dtype: uint8 >>> print(one_hot_encode[3]) 0 0 1 0 2 1 Name: 3, dtype: uint8

    – Deepak

    11 de abril de 2020 a las 4:20


  • No es la herramienta ideal

    – Cerdo Araña

    16 de febrero a las 9:50

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad