"TypeError: (Integer) no es serializable JSON" al serializar JSON en Python?

162

Estoy tratando de enviar un diccionario simple a un archivo json desde python, pero sigo recibiendo el mensaje "TypeError: 1425 no es serializable JSON".

import json
alerts = {'upper':[1425],'lower':[576],'level':[2],'datetime':['2012-08-08 15:30']}
afile = open('test.json','w')
afile.write(json.dumps(alerts,encoding='UTF-8'))
afile.close()

Si agrego el argumento predeterminado, escribe, pero los valores enteros se escriben en el archivo json como cadenas, lo que no es deseable.

afile.write(json.dumps(alerts,encoding='UTF-8',default=str))
usuario1329894
fuente
1
Esto no parece "duplicar" esa pregunta ..
8
Encontré mi problema. El problema era que mis enteros en realidad eran de tipo numpy.int64.
user1329894
@ user1329894 Publicar como solución / explicación y cierre automático ..
-0 por escribir una reproducción mínima que en realidad no reproduce el error.
Russell Borogove

Respuestas:

268

Encontré mi problema. El problema era que mis enteros eran realmente de tipo numpy.int64.

usuario1329894
fuente
22
También tuve que lidiar con este problema, y ​​su respuesta me señaló en la dirección correcta. Solo quería agregar un enlace a otra pregunta que pueda ayudar a resolver el problema.
JAC
19
Eso sería bueno si el mensaje de error no serializable JSON pudiera mostrar el tipo del objeto ...
Franck Dernoncourt
66
Aquí hay una solución ordenada que utiliza un serializador personalizado.
Owen
17
Ese es el problema, pero ¿cuál es la solución?
BallpointBen
55
x.astype (int) o int (x)
zelcon
50

Parece que puede haber un problema al volcar numpy.int64 en la cadena json en Python 3 y el equipo de Python ya tiene una conversación al respecto. Más detalles se pueden encontrar aquí .

Hay una solución provista por Serhiy Storchaka. Funciona muy bien, así que lo pego aquí:

def convert(o):
    if isinstance(o, numpy.int64): return int(o)  
    raise TypeError

json.dumps({'value': numpy.int64(42)}, default=convert)
hsc
fuente
Una maravillosa solución provista por Serhiy. Por favor verifique su enfoque. Y para agregar, solo: json.dumps (yourObject, default = default); como aquí.
Pranzell
4

Esto resolvió mi problema:

def serialize(self):
    return {
        my_int: int(self.my_int), 
        my_float: float(self.my_float)
    }
Tobias Ernst
fuente
4

Simplemente convierta números de int64(de numpy) a int.

Por ejemplo, si variable xes un int64:

int(x)

Si es una matriz de int64:

map(int, x)
Jonatas Eduardo
fuente
3

Como @JAC señaló en los comentarios de la respuesta mejor calificada, la solución genérica (para todos los tipos de numpy) se puede encontrar en el hilo Conversión de tipos de numpy a tipos de python nativos .

Sin embargo, agregaré mi versión de la solución a continuación, ya que en mi caso necesitaba una solución genérica que combine estas respuestas y las respuestas del otro hilo. Esto debería funcionar con casi todos los tipos numpy.

def convert(o):
    if isinstance(o, np.generic): return o.item()  
    raise TypeError

json.dumps({'value': numpy.int64(42)}, default=convert)
Calesa
fuente
Buena respuesta de hecho
jtlz2
2

Esta podría ser la respuesta tardía, pero recientemente recibí el mismo error. Después de mucho navegar, esta solución me ayudó.

alerts = {'upper':[1425],'lower':[576],'level':[2],'datetime':['2012-08-08 15:30']}
def myconverter(obj):
        if isinstance(obj, np.integer):
            return int(obj)
        elif isinstance(obj, np.floating):
            return float(obj)
        elif isinstance(obj, np.ndarray):
            return obj.tolist()
        elif isinstance(obj, datetime.datetime):
            return obj.__str__()

Llamar myconverteren json.dumps()como a continuación.json.dumps(alerts, default=myconverter).

shiva
fuente
1

Alternativamente, puede convertir su objeto en un marco de datos primero:

df = pd.DataFrame(obj)

y luego guarde esto dataframeen un jsonarchivo:

df.to_json(path_or_buf='df.json')

Espero que esto ayude

kartik
fuente
0

Tiene el tipo de datos Numpy, simplemente cambie al tipo de datos int () o float () normal. Funcionará bien.

Sriram Arvind Lakshmanakumar
fuente
0

El mismo problema. La lista contenía números de tipo numpy.int64 que arroja un TypeError. Una solución rápida para mí fue

mylist = eval(str(mylist_of_integers))
json.dumps({'mylist': mylist})

que convierte la lista en str () y la función eval () evalúa la "Cadena" como una expresión de python y, en mi caso, devuelve el resultado como una lista de enteros.

usuario319436
fuente
Acabo de notar que eval (str ()) es muy lento, así que úselo con precaución. La respuesta de @ shiva es mucho mejor: json.dumps (alertas, predeterminado = myconverter)
user319436
0

utilizar

from numpyencoder import NumpyEncoder

para resolver este problema en Python3:

import json
from numpyencoder import NumpyEncoder
alerts = {'upper':[1425],'lower':[576],'level':[2],'datetime':['2012-08-08 
15:30']}
afile = open('test.json','w')
afile.write(json.dumps(alerts,encoding='UTF-8',cls=NumpyEncoder))
afile.close()
krishna kumar mishra
fuente