miércoles, junio 12, 2024
No menu items!
InicioBlogsTres formas de resolver que los objetos en serie sean mutables y...

Tres formas de resolver que los objetos en serie sean mutables y no se puedan aplicar hash (Python)

Aquí encontrará todo sobre TypeError: los objetos de la serie son mutables y no se pueden aplicar hash en Python:

Este error ocurre cuando usa objetos mutables como claves para un diccionario.

Los tipos de datos mutables no pueden ser claves de diccionario y su uso como tales generará un TypeError con el mensaje tipo no compartible.

Entonces, si quieres aprender todo sobre de qué se trata realmente este error en Python y cómo solucionarlo, entonces estás en el lugar correcto.

¡Es hora de dar el primer paso!

Logotipo de arte poligonal del lenguaje de programación Python.

¿Qué pasa con TypeError: los objetos de la serie son mutables y no se pueden aplicar hash en Python?

Para comprender las causas del error TypeError: “Los objetos de la serie son mutables y no se pueden aplicar hash”, primero echemos un vistazo al módulo pandas, ya que es más fácil explicar el error usando este módulo.

¿Qué es el módulo Pandas?

Dos analistas discutiendo datos en una computadora portátil.

Si está comenzando con el análisis de datos, seguramente se encontrará con la biblioteca pandas.

Pandas es una herramienta conveniente para cargar, procesar y guardar rápidamente incluso grandes cantidades de datos tabulares.

Este módulo forma parte de un grupo de proyectos patrocinados por número de enfoque.

NumFocus apoya diversos proyectos relacionados con la informática científica, tales como:

  • numpy
  • Matplotlib
  • picante
  • Aprendizaje científico

La biblioteca de pandas está bien. documentado.

Es ampliamente utilizado y soportado en todo el mundo.

Incluso puedes involucrarte en el desarrollo corrigiendo errores en el proyecto. aquí.

Puedes conectar la biblioteca del panda con el siguiente comando:

importar pandas

Pandas utiliza sus propias estructuras de datos específicas para trabajar con datos de forma rápida y cómoda.

Estas estructuras son:

La serie es una estructura de datos unidimensional etiquetada.

Piense en ello como una tabla con una fila.

Puede trabajar con una serie como una matriz normal (consulte el número de índice) y como una matriz asociada, cuando puede usar una clave para acceder a los elementos de datos.

También puedes pensar en un marco de datos como una colección de series.

El marco de datos es una estructura etiquetada bidimensional.

Es muy similar a una mesa normal.

Pensar en un marco de datos como una tabla le ayudará a comprender cómo crear marcos de datos y trabajar con sus elementos, filas y columnas.

🔥 Leer:  Cómo marcar todos los correos electrónicos como leídos en Gmail

Primero, creemos un objeto de serie a partir de una lista:

ser1 = pd.Series([a, b, c, d, e]) print(ser1) 0 a 1 b 2 c 3 d 4 e dtipo: objeto

Este objeto es bastante simple, pero además de datos, contiene índices.

Estos índices se pueden nombrar para que se parezcan más a una fila de una tabla. Además, pongamos algunos datos dentro de la serie: datos de un agente:

ser2 = pd.Series([192168, John Smith, agent, 120000]índice=[id, name, job_title, salary]) print(ser2) id 192168 nombre John Smith título_trabajo salario del agente 120000 tipo d: objeto

El objeto de serie es unidimensional: sólo puede contener una fila.

Para almacenar varias líneas, necesita un marco de datos.

¿Qué son los objetos mutables y los objetos inmutables en Python?

Tanto las series como los marcos de datos son tipos de datos mutables.

Todos los tipos de datos en Python se dividen en una de dos categorías: mutables e inmutables.

Muchos de los tipos de datos predefinidos de Python son tipos de objetos inmutables, como datos numéricos (int, flotante, complejos), cadenas de caracteres y tuplas.

Otros tipos se definen como mutables, como listas, conjuntos y diccionarios.

Los tipos de usuario (clases) recién definidos se pueden definir como inmutables o mutables.

La mutabilidad de un objeto de un tipo específico es una característica de fundamental importancia que determina si un objeto de este tipo puede actuar o no como clave para diccionarios.

¿Qué son los diccionarios en Python? (3 Soluciones)

Programador concentrándose mientras escribe en el teclado de su computadora.

Los diccionarios representan uno de los tipos (colecciones) integrados y de estructura compleja de Python (junto con listas, tuplas y conjuntos).

Sin embargo, los diccionarios en Python tienen un significado único y exclusivo, ya que el intérprete de Python en sí se basa en diccionarios y el espacio de nombres actual en el punto de ejecución es un diccionario cuyas claves son nombres de objetos.

Las claves de los elementos del diccionario pueden ser valores numéricos, cadenas, tuplas y objetos de sus propias clases, o incluso funciones.

Lo que estos tipos de datos tienen en común es que todos son inmutables.

Los tipos de datos mutables no pueden ser claves de diccionario y su uso como tales generará un TypeError con el mensaje tipo no compartible.

La excepción se generará justo en tiempo de ejecución porque el intérprete no puede determinar la capacidad de hash del tipo de clave antes de ejecutarlo.

Como queda claro, los tipos de datos mutables de Python son tipos de datos para los cuales el valor devuelto por la función hash() no está definido.

Si intentas crear un diccionario cuya clave es el objeto de serie de arriba, obtienes un error:

dic1 = {ser1: Nuestra serie} - TypeError Traceback (última llamada más reciente) en () -> 1 dic1 = {ser1: Nuestra serie} /usr/local/lib/python3.6/dist-packages/pandas/core/generic.py en __hash__(self ) 1667 def __hash__(self): 1668 rise TypeError( -> 1669 f{repr(type(self).__name__)} los objetos son mutables, 1670 fpor lo tanto, no se pueden aplicar hash 1671 ) TypeError: objetos &39;Serie&39; son mutables, por lo que no se pueden aplicar hash

🔥 Leer:  Cómo verificar si los AirPods originales se han actualizado

Puedes comprobar rápidamente si un objeto en particular se puede utilizar para una clave en un diccionario intentando calcular su hash con una función hash especial:

hash(ser2) - TypeError Traceback (última llamada más reciente) en () -> 1 hash(ser2) /usr/local/lib/python3.6/dist-packages/pandas/core/generic.py en __hash__(self) 1667 def __hash__(self): 1668 rise TypeError( -> 1669 f{repr(type(self).__name__)} los objetos son mutables, 1670 fpor lo tanto, no se pueden aplicar hash 1671 )

Puede solucionar este error de varias formas:

Opción n.º 1 para resolver el error de tipo: los objetos de la serie son mutables y no se pueden aplicar hash

Así que NO usemos el objeto serie como clave.

Más bien, utilice sólo uno de sus campos.

Este método es adecuado si el valor del campo es único (por ejemplo, algún número de identificación).

El objeto ser2 tiene un campo identificador.

Es posible crear un diccionario con claves: los valores del campo id en el objeto de serie ser2.

Guardemos el indicativo del agente en él.

Pero primero, compruebe si es posible calcular el hash del campo id de ser2:

hash(ser2[id]) 192168

Como puedes ver, el hash fue evaluado exitosamente, por lo que es posible crear un diccionario con este campo como clave:

dic1 = {ser2[id]: Tigre} print(dic1) {192168: &39;Tigre&39;}

El problema del ejemplo anterior es que, según el diccionario, es difícil decir algo sobre el objeto original.

No almacena todos los datos, sino sólo el identificador, que es difícil de interpretar.

Sin embargo, puede ser incluso más seguro para la tarea de almacenar el indicativo de llamada de un agente.

° 2 para resolver el error de tipo: los objetos de la serie son mutables y no se pueden aplicar hash

La segunda opción es convertir el objeto de la serie en algún tipo inmutable, como una tupla.

Hagamos esto e intentemos calcular el hash de ser2 como una tupla:

tup = tupla(ser2) hash(tup) -2100016149781129293

El hash se calculó correctamente. Creemos un nuevo diccionario e imprimamos:

dic2 = {tup: Tigre} print(dic2) {(192168, &39;John Smith&39;, &39;agente&39;, 120000): &39;Tigre&39;}

Mejor, pero los valores del índice se pierden aquí; puede guardarlos si usa la función zip para vincular los nombres de los campos y sus valores:

tup2 = tupla(zip(ser2.index, ser2)) hash(tup2) 4742336251574250744

Bien, hecho. Ahora hagamos otro diccionario:

dic3 = {tup2: Tigre} print(dic3) {((&39;id&39;, 192168), (&39;nombre&39;, &39;John Smith&39;), (&39;título_trabajo&39;, &39;agente&39;), (&39;salario&39;, 120000 )): &39;Tigre&39;}

Parece amigable y legible, pero no puede referirse al campo por su nombre.

Para obtener el nombre del agente, deberá escribir algo como esto:

lista(dic3.keys())[0][1][1]

John Smith

No parece muy bonito ni conveniente. Sería útil utilizar otro diccionario como clave.

El objeto de serie es algo similar a un diccionario y puedes convertirlo en un diccionario mediante el mismo zip:

🔥 Leer:  ¿Está volviendo a aumentar la popularidad de los juegos móviles?

dic4 = dict(tup2) print(dic4) {&39;id&39;: 192168, &39;nombre&39;: &39;John Smith&39;, &39;job_title&39;: &39;agente&39;, &39;salario&39;: 120000}

Aquí puede acceder a los valores mediante claves, como en el objeto Serie:

dic4[name]
John Smith

Sin embargo, el objeto de diccionario no es hash, como el objeto de serie:

hash(dic4) - TypeError Traceback (última llamada más reciente) en () -> 1 hash(dic4) TypeError: tipo no hashable: &39;dict&39;

Por lo tanto, no puede crear un diccionario con otros diccionarios como claves.

Sin embargo, el módulo de colecciones tiene una estructura de datos que se parece a un diccionario inmutable y con hash llamado nombrado tuple:

de colecciones importar tuple con nombre empleador = nametuple(&39;Empleador&39;, dic4) em1 = empleador(**dic4) print(em1) Empleador(id=192168, nombre=John Smith, job_title=agente, salario=120000)

El objeto llamado tuple es hash, lo que significa que puede ser una clave de diccionario:

hash(em1) -2100016149781129293

Hagamos un diccionario basado en él y mostrémoslo:

dic5 = {em1: Tigre} print(dic5) {Empleador(id=192168, nombre=John Smith, job_title=agente, salario=120000): &39;Tigre&39;}

Ahora puede consultar los campos clave por sus nombres. Por ejemplo, así:

para clave en dic5: print(key.name) print(dic5[key]) John Smith Tigre

° 3 para resolver el error de tipo: los objetos de la serie son mutables y no se pueden aplicar hash

Finalmente, el último método.

Puede crear una clase que heredará de la clase de serie, pero agregarle la función hash.

Puedes tomar el hachís de la forma que más te convenga.

Tenga en cuenta que si el hash cambia repentinamente por algún motivo, este objeto dejará de funcionar como clave:

clase MySeries(pd.Series): def __hash__(self): return hash(tupla(self)) myser = MySeries([192168, John Smith, agent, 120000]índice=[id, name, job_title, salary]) hash(myser) dic = {myser: Tiger} print(dic) {id 192168 nombre John Smith título_trabajo salario del agente 120000 dtype: objeto: &39;Tiger&39;}

Como puede ver, la clave del diccionario ahora es un objeto de nuestra nueva clase MySeries.

Puedes acceder a los valores del diccionario mediante la clave:

dic[myser]
Tigre

Sin embargo, si cambia el hash de su objeto (en el presente caso, puede cambiar la identificación), ya no podrá acceder a los valores del diccionario:

miser[id] = 111111 diciembre[myser]
- KeyError Traceback (última llamada más reciente) en () 1 myser[id] = 111111 -> 2 dic[myser]

KeyError: id 111111 nombre John Smith título_trabajo salario del agente 120000 tipo d: objeto

Cuando intenta acceder a un valor de diccionario mediante un objeto MySeries modificado, obtiene un KeyError.

Este error aparece debido al almacenamiento de datos en el diccionario, que se describe anteriormente.

Al intentar acceder a datos por clave, Python calcula el hash de la clave dada y lo compara con la tabla hash del diccionario.

Por eso está prohibido utilizar objetos mutables como claves. Ya has visto anteriormente cómo solucionar este problema si realmente lo necesitas, pero utiliza este método con extrema precaución.

Aquí hay más soporte para Python:

Recomendamos

Populares