193

I am trying to send a simple dictionary to a json file from python, but I keep getting the "TypeError: 1425 is not JSON serializable" message.

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

If I add the default argument, then it writes, but the integer values are written to the json file as strings, which is undesirable.

afile.write(json.dumps(alerts,encoding='UTF-8',default=str))
user1329894
  • 5,027
  • 4
  • 15
  • 7
  • 1
    This doesn't appear to "duplicate" that question .. –  Aug 13 '12 at 21:17
  • 14
    I found my problem. The issue was that my integers were actually type numpy.int64. – user1329894 Aug 13 '12 at 21:18
  • @user1329894 Post as a solution/explanation and self-close .. –  Aug 13 '12 at 21:19
  • -0 for writing a minimal repro that doesn't actually reproduce the bug. – Russell Borogove Aug 13 '12 at 21:39
  • The underlying problem is the same: data that looks like an "ordinary" type, but is a different type that doesn't support serialization. In this case it was a Numpy numeric type instead of `int`; in the other case, a custom mapping instead of `dict`. – Karl Knechtel Sep 08 '22 at 07:06

10 Answers10

305

I found my problem. The issue was that my integers were actually type numpy.int64.

Andrea Bergonzo
  • 3,983
  • 4
  • 19
  • 31
user1329894
  • 5,027
  • 4
  • 15
  • 7
70

It seems like there may be a issue to dump numpy.int64 into json string in Python 3 and the python team already have a conversation about it. More details can be found here.

There is a workaround provided by Serhiy Storchaka. It works very well so I paste it here:

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

json.dumps({'value': numpy.int64(42)}, default=convert)
hsc
  • 1,226
  • 11
  • 24
  • A wonderful workaround provided by Serhiy. Please check his approach. And to add, just: json.dumps(yourObject, default=default); like here. – Pranzell Apr 16 '19 at 15:30
13

as @JAC pointed out in the comments of the highest rated answer, the generic solution (for all numpy types) can be found in the thread Converting numpy dtypes to native python types.

Nevertheless, I´ll add my version of the solution below, as my in my case I needed a generic solution that combines these answers and with the answers of the other thread. This should work with almost all numpy types.

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

json.dumps({'value': numpy.int64(42)}, default=convert)
Buggy
  • 2,050
  • 21
  • 27
10

Just convert numbers from int64 (from numpy) to int.

For example, if variable x is a int64:

int(x)

If is array of int64:

map(int, x)
Jonatas Eduardo
  • 834
  • 9
  • 18
8

You have Numpy Data Type, Just change to normal int() or float() data type. it will work fine.

shiva
  • 5,083
  • 5
  • 23
  • 42
6

This might be the late response, but recently i got the same error. After lot of surfing this solution helped me.

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__()

Call myconverter in json.dumps() like below. json.dumps(alerts, default=myconverter).

shiva
  • 5,083
  • 5
  • 23
  • 42
4

This solved the problem for me:

def serialize(self):
    return {
        my_int: int(self.my_int), 
        my_float: float(self.my_float)
    }
Tobias Ernst
  • 4,214
  • 1
  • 32
  • 30
4

Same problem. List contained numbers of type numpy.int64 which throws a TypeError. Quick workaround for me was to

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

which converts list to str() and eval() function evaluates the String like a Python expression and returns the result as a list of integers in my case.

shiva
  • 5,083
  • 5
  • 23
  • 42
user319436
  • 173
  • 12
  • Just noticed eval(str()) is very slow so use with caution. @shiva's answer is much better: json.dumps(alerts, default=myconverter) – user319436 Apr 24 '20 at 00:06
3

Use the below code to resolve the issue.

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()
shiva
  • 5,083
  • 5
  • 23
  • 42
1

Alternatively you can convert your object into a dataframe first:

df = pd.DataFrame(obj)

and then save this dataframe in a json file:

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

Hope this helps

toti08
  • 2,448
  • 5
  • 24
  • 36
kartik
  • 11
  • 1