Skip to content

Commit

Permalink
Backport PR pandas-dev#57232: REGR: to_json converting nullable ints …
Browse files Browse the repository at this point in the history
…to floats
  • Loading branch information
phofl authored and meeseeksmachine committed Feb 4, 2024
1 parent 5034b78 commit dcb58b6
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 0 deletions.
1 change: 1 addition & 0 deletions doc/source/whatsnew/v2.2.1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Fixed regressions
- Fixed regression in :meth:`DataFrame.loc` raising ``IndexError`` for non-unique, masked dtype indexes where result has more than 10,000 rows (:issue:`57027`)
- Fixed regression in :meth:`DataFrame.sort_index` not producing a stable sort for a index with duplicates (:issue:`57151`)
- Fixed regression in :meth:`DataFrame.to_dict` with ``orient='list'`` and datetime or timedelta types returning integers (:issue:`54824`)
- Fixed regression in :meth:`DataFrame.to_json` converting nullable integers to floats (:issue:`57224`)
- Fixed regression in :meth:`DataFrameGroupBy.idxmin`, :meth:`DataFrameGroupBy.idxmax`, :meth:`SeriesGroupBy.idxmin`, :meth:`SeriesGroupBy.idxmax` ignoring the ``skipna`` argument (:issue:`57040`)
- Fixed regression in :meth:`DataFrameGroupBy.idxmin`, :meth:`DataFrameGroupBy.idxmax`, :meth:`SeriesGroupBy.idxmin`, :meth:`SeriesGroupBy.idxmax` where values containing the minimum or maximum value for the dtype could produce incorrect results (:issue:`57040`)
- Fixed regression in :meth:`Index.join` raising ``TypeError`` when joining an empty index to a non-empty index containing mixed dtype values (:issue:`57048`)
Expand Down
5 changes: 5 additions & 0 deletions pandas/core/arrays/arrow/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,11 @@ def _to_timedeltaarray(self) -> TimedeltaArray:
np_array = np_array.astype(np_dtype)
return TimedeltaArray._simple_new(np_array, dtype=np_dtype)

def _values_for_json(self) -> np.ndarray:
if is_numeric_dtype(self.dtype):
return np.asarray(self, dtype=object)
return super()._values_for_json()

@doc(ExtensionArray.to_numpy)
def to_numpy(
self,
Expand Down
3 changes: 3 additions & 0 deletions pandas/core/arrays/masked.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,9 @@ def __abs__(self) -> Self:

# ------------------------------------------------------------------

def _values_for_json(self) -> np.ndarray:
return np.asarray(self, dtype=object)

def to_numpy(
self,
dtype: npt.DTypeLike | None = None,
Expand Down
16 changes: 16 additions & 0 deletions pandas/tests/io/json/test_pandas.py
Original file line number Diff line number Diff line change
Expand Up @@ -2172,3 +2172,19 @@ def test_json_pos_args_deprecation():
with tm.assert_produces_warning(FutureWarning, match=msg):
buf = BytesIO()
df.to_json(buf, "split")


@td.skip_if_no("pyarrow")
def test_to_json_ea_null():
# GH#57224
df = DataFrame(
{
"a": Series([1, NA], dtype="int64[pyarrow]"),
"b": Series([2, NA], dtype="Int64"),
}
)
result = df.to_json(orient="records", lines=True)
expected = """{"a":1,"b":2}
{"a":null,"b":null}
"""
assert result == expected

0 comments on commit dcb58b6

Please sign in to comment.