Skip to content

Commit 715118e

Browse files
BUG: Fixed encoding of pd.NA with to_json GH31615
1 parent a2a35a8 commit 715118e

File tree

3 files changed

+23
-2
lines changed

3 files changed

+23
-2
lines changed

doc/source/whatsnew/v1.0.2.rst

Lines changed: 3 additions & 2 deletions
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

Lines changed: 12 additions & 0 deletions
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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1671,3 +1671,11 @@ 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+
@pytest.mark.parametrize(
1676+
"dataframe,expected", [(pd.DataFrame([[pd.NA]]), '{"0":{"0":null}}',)],
1677+
)
1678+
def test_json_pandas_na(self, dataframe, expected):
1679+
# GH 31615
1680+
result = dataframe.to_json()
1681+
assert result == expected

0 commit comments

Comments
 (0)