Skip to content

Commit 0bfb8cb

Browse files
BUG: Fixed encoding of pd.NA with to_json (pandas-dev#31748)
1 parent e2b47ce commit 0bfb8cb

File tree

3 files changed

+25
-2
lines changed

3 files changed

+25
-2
lines changed

doc/source/whatsnew/v1.0.2.rst

+3-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ Fixed regressions
2525
Bug fixes
2626
~~~~~~~~~
2727

28-
-
29-
-
28+
**I/O**
29+
30+
- Using ``pd.NA`` with :meth:`DataFrame.to_json` now correctly outputs a null value instead of an empty object (:issue:`31615`)
3031

3132
.. ---------------------------------------------------------------------------
3233

pandas/_libs/src/ujson/python/objToJSON.c

+12
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ static PyTypeObject *cls_dataframe;
5353
static PyTypeObject *cls_series;
5454
static PyTypeObject *cls_index;
5555
static PyTypeObject *cls_nat;
56+
static PyTypeObject *cls_na;
5657
PyObject *cls_timedelta;
5758

5859
npy_int64 get_nat(void) { return NPY_MIN_INT64; }
@@ -149,6 +150,7 @@ int PdBlock_iterNext(JSOBJ, JSONTypeContext *);
149150
void *initObjToJSON(void) {
150151
PyObject *mod_pandas;
151152
PyObject *mod_nattype;
153+
PyObject *mod_natype;
152154
PyObject *mod_decimal = PyImport_ImportModule("decimal");
153155
type_decimal =
154156
(PyTypeObject *)PyObject_GetAttrString(mod_decimal, "Decimal");
@@ -174,6 +176,12 @@ void *initObjToJSON(void) {
174176
Py_DECREF(mod_nattype);
175177
}
176178

179+
mod_natype = PyImport_ImportModule("pandas._libs.missing");
180+
if (mod_natype) {
181+
cls_na = (PyTypeObject *)PyObject_GetAttrString(mod_natype, "NAType");
182+
Py_DECREF(mod_natype);
183+
}
184+
177185
/* Initialise numpy API */
178186
import_array();
179187
// GH 31463
@@ -1789,6 +1797,10 @@ void Object_beginTypeContext(JSOBJ _obj, JSONTypeContext *tc) {
17891797
"%R (0d array) is not JSON serializable at the moment",
17901798
obj);
17911799
goto INVALID;
1800+
} else if (PyObject_TypeCheck(obj, cls_na)) {
1801+
PRINTMARK();
1802+
tc->type = JT_NULL;
1803+
return;
17921804
}
17931805

17941806
ISITERABLE:

pandas/tests/io/json/test_pandas.py

+10
Original file line numberDiff line numberDiff line change
@@ -1671,3 +1671,13 @@ def test_to_s3(self, s3_resource):
16711671
assert target_file in (
16721672
obj.key for obj in s3_resource.Bucket("pandas-test").objects.all()
16731673
)
1674+
1675+
def test_json_pandas_na(self):
1676+
# GH 31615
1677+
result = pd.DataFrame([[pd.NA]]).to_json()
1678+
assert result == '{"0":{"0":null}}'
1679+
1680+
def test_json_pandas_nulls(self, nulls_fixture):
1681+
# GH 31615
1682+
result = pd.DataFrame([[nulls_fixture]]).to_json()
1683+
assert result == '{"0":{"0":null}}'

0 commit comments

Comments
 (0)