86

I'm working with numpy.float32 numbers and they don't go into JSON. What's the right approach to overcome this issue?

import numpy as np
import json

a = np.float32(1)
json.dumps(a)

TypeError: Object of type 'float32' is not JSON serializable
Franco Piccolo
  • 6,845
  • 8
  • 34
  • 52
  • 4
    The accepted answer actually produces a string of a serialized object, which in fact is a json string, but not an object. I found that `json.dumps(eval(str(a)))` will produce the desired output – Peavey Dec 12 '20 at 12:50
  • For me the simplest thing is to transform your float32 to float64, then I would be handled by JSON. The accepted answer transform produces a string which isn't very practical. – Wassim Bouatay Jan 03 '22 at 15:29

1 Answers1

61

It has to be a string, so you can have:

json.dumps(str(a))

EDIT:

JSON is a format for serialising object data. It doesn't really care or know about Python types, the json package tries to translate whatever object you pass json.dumps() into a string form via a conversion table that only supports some types (see doc below).

This is the reason why I think it's a good idea to just pass a string to avoid this issue: numpy.float32 just isn't in the table.

Because some have commented that explicitly passing a string to dumps "sounds wrong" I'll just add the doc here

json.dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw) Serialize obj to a JSON formatted str using this conversion table. The arguments have the same meaning as in dump().

Note Keys in key/value pairs of JSON are always of the type str. When a dictionary is converted into JSON, all the keys of the dictionary are coerced to strings. As a result of this, if a dictionary is converted into JSON and then back into a dictionary, the dictionary may not equal the original one. That is, loads(dumps(x)) != x if x has non-string keys.

taken from the official docs here: https://docs.python.org/3/library/json.html

Danijel
  • 8,198
  • 18
  • 69
  • 133
vencaslac
  • 2,727
  • 1
  • 18
  • 29
  • 47
    This would change the type of `a` to string. If you want to keep `a` as a number, use `json.dumps(a.item())`. – Domenico De Felice Nov 17 '18 at 09:28
  • 10
    If you don't need the data to be in numpy float format in your application (which is the case for most appl.), then I suggest you convert the results of numpy ops that return np.float32 to float before adding them to your dicts/lists which you later want to serialize; e.g, `dict_to_be_jsoned[key0] = float(np.somefunc(...))` – Oliver Zendel Apr 09 '19 at 13:27
  • 7
    Statemen "it has to be a string" seems wrong, @DomenicoDeFelice suggested a better solution in his comment. – Danijel Nov 20 '19 at 10:28
  • @Danijel see edit above – vencaslac Nov 20 '19 at 12:34
  • 13
    `json.dumps(a.astype(float))` – mac13k Dec 28 '19 at 17:24
  • 9
    or `json.dumps(float(a))` – Jonathan Dec 01 '20 at 14:59
  • 1
    @Jonathon @mac13k In this case is `a` is a simple number, but in general it could be a more complex json compliant data structure, like a whole dictionary. So simply casting isn't the most extensible approach – Jordan Simba Dec 02 '20 at 13:59
  • to add to @JordanSimba's comment for mac13k and Jonathan the use case involving numpy.float32 would actually stand to lose from converting to native float since you would lose floating point precision – vencaslac Dec 02 '20 at 14:32
  • 1
    This is how it worked for me. json.dumps(eval(str(final_output))) – Wesam Na Jan 03 '21 at 11:10
  • 1
    Much simpler to convert to float, as Oliver Zendel pointed out. – Wok Jan 31 '21 at 17:18
  • if you convert to float you're setting yourself up for the floating point errors that numpy.float32 was created to avoid, just convert to string... it really saves a lot of hassle – vencaslac Feb 04 '21 at 20:45
  • 3
    This answer is wrong. Only dict keys have to be strings in JSON; the values can be integer or float numbers, list, dicts, etc. Therefore, it is not necessary to convert numbers to strings to save them as JSON. – David Dale Nov 20 '21 at 21:46
  • @DavidDale, the json library only supports some types, common ones such as the ones you mentioned, the reason you would convert to string is because numpy.float32 is not supported by the conversion table in the library, so you have to work around it by converting to string, if you cast it to float you might lose some floating point precision, so you cast to string – vencaslac Nov 22 '21 at 08:53