diff --git a/doc/source/whatsnew/index.rst b/doc/source/whatsnew/index.rst index 1dd6c5fabef04..9da73c8fd76d4 100644 --- a/doc/source/whatsnew/index.rst +++ b/doc/source/whatsnew/index.rst @@ -24,6 +24,7 @@ Version 2.3 .. toctree:: :maxdepth: 2 + v2.3.1 v2.3.0 Version 2.2 diff --git a/doc/source/whatsnew/v2.3.1.rst b/doc/source/whatsnew/v2.3.1.rst new file mode 100644 index 0000000000000..0edb8bc3181c2 --- /dev/null +++ b/doc/source/whatsnew/v2.3.1.rst @@ -0,0 +1,44 @@ +.. _whatsnew_231: + +What's new in 2.3.1 (Month XX, 2025) +--------------------------------------- + +These are the changes in pandas 2.3.1. See :ref:`release` for a full changelog +including other versions of pandas. + +{{ header }} + +.. --------------------------------------------------------------------------- +.. _whatsnew_231.enhancements: + +Enhancements +~~~~~~~~~~~~ +- + +.. _whatsnew_231.regressions: + +Fixed regressions +~~~~~~~~~~~~~~~~~ +- + +.. --------------------------------------------------------------------------- +.. _whatsnew_231.bug_fixes: + +Bug fixes +~~~~~~~~~ +- Fixed bug in :meth:`DataFrame.explode` and :meth:`Series.explode` where methods would fail with ``dtype="str"`` (:issue:`61623`) + +.. --------------------------------------------------------------------------- +.. _whatsnew_231.other: + +Other +~~~~~ +- + +.. --------------------------------------------------------------------------- +.. _whatsnew_231.contributors: + +Contributors +~~~~~~~~~~~~ + +.. contributors:: v2.3.0..v2.3.1 diff --git a/pandas/core/arrays/arrow/array.py b/pandas/core/arrays/arrow/array.py index 0b90bcea35100..c18f06c3a126d 100644 --- a/pandas/core/arrays/arrow/array.py +++ b/pandas/core/arrays/arrow/array.py @@ -1935,9 +1935,9 @@ def _explode(self): """ # child class explode method supports only list types; return # default implementation for non list types. - if not ( - pa.types.is_list(self.dtype.pyarrow_dtype) - or pa.types.is_large_list(self.dtype.pyarrow_dtype) + if not hasattr(self.dtype, "pyarrow_dtype") or ( + not pa.types.is_list(self.dtype.pyarrow_dtype) + and not pa.types.is_large_list(self.dtype.pyarrow_dtype) ): return super()._explode() values = self diff --git a/pandas/tests/frame/methods/test_explode.py b/pandas/tests/frame/methods/test_explode.py index 876ad5539d603..cfb85d261d07a 100644 --- a/pandas/tests/frame/methods/test_explode.py +++ b/pandas/tests/frame/methods/test_explode.py @@ -297,3 +297,11 @@ def test_multi_columns_nan_empty(): index=[0, 0, 1, 2, 3, 3], ) tm.assert_frame_equal(result, expected) + + +def test_str_dtype(): + # https://github.com/pandas-dev/pandas/pull/61623 + df = pd.DataFrame({"a": ["x", "y"]}, dtype="str") + result = df.explode(column="a") + assert result is not df + tm.assert_frame_equal(result, df) diff --git a/pandas/tests/series/methods/test_explode.py b/pandas/tests/series/methods/test_explode.py index e4ad2493f9bb9..9c08f47c0d678 100644 --- a/pandas/tests/series/methods/test_explode.py +++ b/pandas/tests/series/methods/test_explode.py @@ -175,3 +175,11 @@ def test_explode_pyarrow_non_list_type(ignore_index): result = ser.explode(ignore_index=ignore_index) expected = pd.Series([1, 2, 3], dtype="int64[pyarrow]", index=[0, 1, 2]) tm.assert_series_equal(result, expected) + + +def test_str_dtype(): + # https://github.com/pandas-dev/pandas/pull/61623 + ser = pd.Series(["x", "y"], dtype="str") + result = ser.explode() + assert result is not ser + tm.assert_series_equal(result, ser)