From a2e58f90286043a81cf4d01e3456c80095bc7729 Mon Sep 17 00:00:00 2001 From: Santhosh18 Date: Fri, 26 Jun 2020 17:11:01 +0530 Subject: [PATCH 1/8] Inferred dtype at the end of df.explode() --- pandas/core/frame.py | 1 + pandas/tests/series/methods/test_explode.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index f52341ed782d8..372a989ce0ffd 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -7070,6 +7070,7 @@ def explode( else: result.index = self.index.take(result.index) result = result.reindex(columns=self.columns, copy=False) + result = result.infer_objects() return result diff --git a/pandas/tests/series/methods/test_explode.py b/pandas/tests/series/methods/test_explode.py index 4b65e042f7b02..ad2050ab2cc05 100644 --- a/pandas/tests/series/methods/test_explode.py +++ b/pandas/tests/series/methods/test_explode.py @@ -7,7 +7,7 @@ def test_basic(): s = pd.Series([[0, 1, 2], np.nan, [], (3, 4)], index=list("abcd"), name="foo") - result = s.explode() + result = s. explode() expected = pd.Series( [0, 1, 2, np.nan, np.nan, 3, 4], index=list("aaabcdd"), dtype=object, name="foo" ) From 1ead55f19ec3b16a997c1fb2d480f7dffef6b0ae Mon Sep 17 00:00:00 2001 From: Santhosh18 Date: Fri, 26 Jun 2020 17:23:20 +0530 Subject: [PATCH 2/8] Fixed PEP issues --- pandas/tests/series/methods/test_explode.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/tests/series/methods/test_explode.py b/pandas/tests/series/methods/test_explode.py index ad2050ab2cc05..5c8016f6d8b8b 100644 --- a/pandas/tests/series/methods/test_explode.py +++ b/pandas/tests/series/methods/test_explode.py @@ -126,3 +126,4 @@ def test_ignore_index(): result = s.explode(ignore_index=True) expected = pd.Series([1, 2, 3, 4], index=[0, 1, 2, 3], dtype=object) tm.assert_series_equal(result, expected) + From 86f5f5f97d1d157d4d1386c3d23b3e6f4a2482fd Mon Sep 17 00:00:00 2001 From: Santhosh18 Date: Fri, 26 Jun 2020 20:03:25 +0530 Subject: [PATCH 3/8] Modified test cases and added detailed explanation in v1.1.0.rst --- doc/source/whatsnew/v1.1.0.rst | 70 +++++++++++++++++++++ pandas/core/series.py | 2 +- pandas/tests/frame/methods/test_explode.py | 25 ++++++-- pandas/tests/series/methods/test_explode.py | 10 +-- 4 files changed, 96 insertions(+), 11 deletions(-) diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index 43d1244c15d8a..619419206c3b1 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -715,6 +715,76 @@ apply and applymap on ``DataFrame`` evaluates first row/column only once df.apply(func, axis=1) + +.. _whatsnew_110.api_breaking.explode_infer_dtype: + +Infer dtypes in explode method for Dataframe and Series +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Using :meth:`DataFrame.explode` and :meth:`Series.explode` would always return an object for the column being exploded. Now the dtype of the column would be inferred and returned accordingly. (:issue:`34923`) + +.. ipython:: python + + s = pd.Series([1,2,3]) + df = pd.DataFrame({'A': [s, s, s, s], 'B': 1}) + +*Previous behavior*: + +.. code-block:: ipython + + In [3]: df.explode("A").dtypes + Out[3]: + A object + B int64 + dtype: object + +*New behavior*: + +.. ipython:: ipython + + In [3]: df.explode("A").dtypes + Out[3]: + A int64 + B int64 + dtype: object + +.. _whatsnew_110.api.other: + +Other API changes +^^^^^^^^^^^^^^^^^ + +- :meth:`Series.describe` will now show distribution percentiles for ``datetime`` dtypes, statistics ``first`` and ``last`` + will now be ``min`` and ``max`` to match with numeric dtypes in :meth:`DataFrame.describe` (:issue:`30164`) +- Added :meth:`DataFrame.value_counts` (:issue:`5377`) +- :meth:`Groupby.groups` now returns an abbreviated representation when called on large dataframes (:issue:`1135`) +- ``loc`` lookups with an object-dtype :class:`Index` and an integer key will now raise ``KeyError`` instead of ``TypeError`` when key is missing (:issue:`31905`) +- Using a :func:`pandas.api.indexers.BaseIndexer` with ``count``, ``min``, ``max``, ``median``, ``skew``, ``cov``, ``corr`` will now return correct results for any monotonic :func:`pandas.api.indexers.BaseIndexer` descendant (:issue:`32865`) +- Added a :func:`pandas.api.indexers.FixedForwardWindowIndexer` class to support forward-looking windows during ``rolling`` operations. +- Added a :func:`pandas.api.indexers.NonFixedVariableWindowIndexer` class to support ``rolling`` operations with non-fixed offsets (:issue:`34994`) +- Added :class:`pandas.errors.InvalidIndexError` (:issue:`34570`). +- :meth:`DataFrame.swaplevels` now raises a ``TypeError`` if the axis is not a :class:`MultiIndex`. + Previously an ``AttributeError`` was raised (:issue:`31126`) +- :meth:`DataFrame.xs` now raises a ``TypeError`` if a ``level`` keyword is supplied and the axis is not a :class:`MultiIndex`. + Previously an ``AttributeError`` was raised (:issue:`33610`) +- :meth:`DataFrameGroupby.mean` and :meth:`SeriesGroupby.mean` (and similarly for :meth:`~DataFrameGroupby.median`, :meth:`~DataFrameGroupby.std` and :meth:`~DataFrameGroupby.var`) + now raise a ``TypeError`` if a not-accepted keyword argument is passed into it. + Previously a ``UnsupportedFunctionCall`` was raised (``AssertionError`` if ``min_count`` passed into :meth:`~DataFrameGroupby.median`) (:issue:`31485`) +- :meth:`DataFrame.at` and :meth:`Series.at` will raise a ``TypeError`` instead of a ``ValueError`` if an incompatible key is passed, and ``KeyError`` if a missing key is passed, matching the behavior of ``.loc[]`` (:issue:`31722`) +- Passing an integer dtype other than ``int64`` to ``np.array(period_index, dtype=...)`` will now raise ``TypeError`` instead of incorrectly using ``int64`` (:issue:`32255`) +- Passing an invalid ``fill_value`` to :meth:`Categorical.take` raises a ``ValueError`` instead of ``TypeError`` (:issue:`33660`) +- Combining a ``Categorical`` with integer categories and which contains missing values + with a float dtype column in operations such as :func:`concat` or :meth:`~DataFrame.append` + will now result in a float column instead of an object dtyped column (:issue:`33607`) +- :meth:`Series.to_timestamp` now raises a ``TypeError`` if the axis is not a :class:`PeriodIndex`. Previously an ``AttributeError`` was raised (:issue:`33327`) +- :meth:`Series.to_period` now raises a ``TypeError`` if the axis is not a :class:`DatetimeIndex`. Previously an ``AttributeError`` was raised (:issue:`33327`) +- :func: `pandas.api.dtypes.is_string_dtype` no longer incorrectly identifies categorical series as string. +- :func:`read_excel` no longer takes ``**kwds`` arguments. This means that passing in keyword ``chunksize`` now raises a ``TypeError`` + (previously raised a ``NotImplementedError``), while passing in keyword ``encoding`` now raises a ``TypeError`` (:issue:`34464`) +- :func: `merge` now checks ``suffixes`` parameter type to be ``tuple`` and raises ``TypeError``, whereas before a ``list`` or ``set`` were accepted and that the ``set`` could produce unexpected results (:issue:`33740`) +- :class:`Period` no longer accepts tuples for the ``freq`` argument (:issue:`34658`) +- :meth:`Series.interpolate` and :meth:`DataFrame.interpolate` now raises ValueError if ``limit_direction`` is 'forward' or 'both' and ``method`` is 'backfill' or 'bfill' or ``limit_direction`` is 'backward' or 'both' and ``method`` is 'pad' or 'ffill' (:issue:`34746`) + + Increased minimum versions for dependencies ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/pandas/core/series.py b/pandas/core/series.py index ef3be854bc3bb..b3e9be26038c8 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -3843,7 +3843,7 @@ def explode(self, ignore_index: bool = False) -> "Series": else: index = self.index.repeat(counts) - result = self._constructor(values, index=index, name=self.name) + result = self._constructor(values, index=index, name=self.name).infer_objects() return result diff --git a/pandas/tests/frame/methods/test_explode.py b/pandas/tests/frame/methods/test_explode.py index 2bbe8ac2d5b81..f34a2ef766ca6 100644 --- a/pandas/tests/frame/methods/test_explode.py +++ b/pandas/tests/frame/methods/test_explode.py @@ -25,7 +25,7 @@ def test_basic(): expected = pd.DataFrame( { "A": pd.Series( - [0, 1, 2, np.nan, np.nan, 3, 4], index=list("aaabcdd"), dtype=object + [0, 1, 2, np.nan, np.nan, 3, 4], index=list("aaabcdd"), dtype=np.float64 ), "B": 1, } @@ -55,7 +55,7 @@ def test_multi_index_rows(): ("b", 2), ] ), - dtype=object, + dtype=np.float64, ), "B": 1, } @@ -74,7 +74,7 @@ def test_multi_index_columns(): ("A", 1): pd.Series( [0, 1, 2, np.nan, np.nan, 3, 4], index=pd.Index([0, 0, 0, 1, 2, 3, 3]), - dtype=object, + dtype=np.float64, ), ("A", 2): 1, } @@ -93,7 +93,7 @@ def test_usecase(): expected = pd.DataFrame( { "A": [11, 11, 11, 11, 11, 22, 22, 22], - "B": np.array([0, 1, 2, 3, 4, 0, 1, 2], dtype=object), + "B": np.array([0, 1, 2, 3, 4, 0, 1, 2], dtype=np.int64), "C": [10, 10, 10, 10, 10, 20, 20, 20], }, columns=list("ABC"), @@ -160,7 +160,22 @@ def test_duplicate_index(input_dict, input_index, expected_dict, expected_index) # GH 28005 df = pd.DataFrame(input_dict, index=input_index) result = df.explode("col1") - expected = pd.DataFrame(expected_dict, index=expected_index, dtype=object) + expected = pd.DataFrame(expected_dict, index=expected_index, dtype=np.int64) + tm.assert_frame_equal(result, expected) + + +def test_inferred_dtype(): + # GH 34923 + s = pd.Series([1, None, 3]) + df = pd.DataFrame({'A': [s, s], "B": 1}) + result = df.explode("A") + expected = pd.DataFrame( + { + "A": np.array([1, np.nan, 3, 1, np.nan, 3], dtype=np.float64), + "B": np.array([1, 1, 1, 1, 1, 1], dtype=np.int64) + }, + index=[0, 0, 0, 1, 1, 1] + ) tm.assert_frame_equal(result, expected) diff --git a/pandas/tests/series/methods/test_explode.py b/pandas/tests/series/methods/test_explode.py index 5c8016f6d8b8b..58aba1e52d722 100644 --- a/pandas/tests/series/methods/test_explode.py +++ b/pandas/tests/series/methods/test_explode.py @@ -7,9 +7,9 @@ def test_basic(): s = pd.Series([[0, 1, 2], np.nan, [], (3, 4)], index=list("abcd"), name="foo") - result = s. explode() + result = s.explode() expected = pd.Series( - [0, 1, 2, np.nan, np.nan, 3, 4], index=list("aaabcdd"), dtype=object, name="foo" + [0, 1, 2, np.nan, np.nan, 3, 4], index=list("aaabcdd"), dtype=np.float64, name="foo" ) tm.assert_series_equal(result, expected) @@ -54,7 +54,7 @@ def test_multi_index(): names=["foo", "bar"], ) expected = pd.Series( - [0, 1, 2, np.nan, np.nan, 3, 4], index=index, dtype=object, name="foo" + [0, 1, 2, np.nan, np.nan, 3, 4], index=index, dtype=np.float64, name="foo" ) tm.assert_series_equal(result, expected) @@ -116,7 +116,7 @@ def test_duplicate_index(): # GH 28005 s = pd.Series([[1, 2], [3, 4]], index=[0, 0]) result = s.explode() - expected = pd.Series([1, 2, 3, 4], index=[0, 0, 0, 0], dtype=object) + expected = pd.Series([1, 2, 3, 4], index=[0, 0, 0, 0], dtype=np.int64) tm.assert_series_equal(result, expected) @@ -124,6 +124,6 @@ def test_ignore_index(): # GH 34932 s = pd.Series([[1, 2], [3, 4]]) result = s.explode(ignore_index=True) - expected = pd.Series([1, 2, 3, 4], index=[0, 1, 2, 3], dtype=object) + expected = pd.Series([1, 2, 3, 4], index=[0, 1, 2, 3], dtype=np.int64) tm.assert_series_equal(result, expected) From 8b3e07b9d953392dd3fd5c01f18750463b4f3080 Mon Sep 17 00:00:00 2001 From: Santhosh18 Date: Mon, 29 Jun 2020 18:28:09 +0530 Subject: [PATCH 4/8] Fixed Linting issues --- doc/source/whatsnew/v1.1.0.rst | 2 +- pandas/tests/series/methods/test_explode.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index 619419206c3b1..2d2cd386c9e60 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -725,7 +725,7 @@ Using :meth:`DataFrame.explode` and :meth:`Series.explode` would always return a .. ipython:: python - s = pd.Series([1,2,3]) + s = pd.Series([1, 2, 3]) df = pd.DataFrame({'A': [s, s, s, s], 'B': 1}) *Previous behavior*: diff --git a/pandas/tests/series/methods/test_explode.py b/pandas/tests/series/methods/test_explode.py index 58aba1e52d722..3f6d31daa979e 100644 --- a/pandas/tests/series/methods/test_explode.py +++ b/pandas/tests/series/methods/test_explode.py @@ -9,7 +9,8 @@ def test_basic(): s = pd.Series([[0, 1, 2], np.nan, [], (3, 4)], index=list("abcd"), name="foo") result = s.explode() expected = pd.Series( - [0, 1, 2, np.nan, np.nan, 3, 4], index=list("aaabcdd"), dtype=np.float64, name="foo" + [0, 1, 2, np.nan, np.nan, 3, 4], index=list("aaabcdd"), + dtype=np.float64, name="foo" ) tm.assert_series_equal(result, expected) From 2c1071c1ace6275962118e32bc0e232e7f8291f2 Mon Sep 17 00:00:00 2001 From: Santhosh18 Date: Tue, 30 Jun 2020 12:37:51 +0530 Subject: [PATCH 5/8] Fixed PEP issues --- pandas/tests/series/methods/test_explode.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/tests/series/methods/test_explode.py b/pandas/tests/series/methods/test_explode.py index 3f6d31daa979e..de2bf4c6379f8 100644 --- a/pandas/tests/series/methods/test_explode.py +++ b/pandas/tests/series/methods/test_explode.py @@ -127,4 +127,3 @@ def test_ignore_index(): result = s.explode(ignore_index=True) expected = pd.Series([1, 2, 3, 4], index=[0, 1, 2, 3], dtype=np.int64) tm.assert_series_equal(result, expected) - From 7ba1472f1cc0ca0e6cd8392f5523ca9ccff309fb Mon Sep 17 00:00:00 2001 From: Santhosh18 Date: Tue, 30 Jun 2020 14:11:43 +0530 Subject: [PATCH 6/8] Fixed linting issues --- pandas/tests/frame/methods/test_explode.py | 6 +++--- pandas/tests/series/methods/test_explode.py | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/pandas/tests/frame/methods/test_explode.py b/pandas/tests/frame/methods/test_explode.py index f34a2ef766ca6..064f6936d6d0e 100644 --- a/pandas/tests/frame/methods/test_explode.py +++ b/pandas/tests/frame/methods/test_explode.py @@ -167,14 +167,14 @@ def test_duplicate_index(input_dict, input_index, expected_dict, expected_index) def test_inferred_dtype(): # GH 34923 s = pd.Series([1, None, 3]) - df = pd.DataFrame({'A': [s, s], "B": 1}) + df = pd.DataFrame({"A": [s, s], "B": 1}) result = df.explode("A") expected = pd.DataFrame( { "A": np.array([1, np.nan, 3, 1, np.nan, 3], dtype=np.float64), - "B": np.array([1, 1, 1, 1, 1, 1], dtype=np.int64) + "B": np.array([1, 1, 1, 1, 1, 1], dtype=np.int64), }, - index=[0, 0, 0, 1, 1, 1] + index=[0, 0, 0, 1, 1, 1], ) tm.assert_frame_equal(result, expected) diff --git a/pandas/tests/series/methods/test_explode.py b/pandas/tests/series/methods/test_explode.py index de2bf4c6379f8..b720d7a23b375 100644 --- a/pandas/tests/series/methods/test_explode.py +++ b/pandas/tests/series/methods/test_explode.py @@ -9,8 +9,10 @@ def test_basic(): s = pd.Series([[0, 1, 2], np.nan, [], (3, 4)], index=list("abcd"), name="foo") result = s.explode() expected = pd.Series( - [0, 1, 2, np.nan, np.nan, 3, 4], index=list("aaabcdd"), - dtype=np.float64, name="foo" + [0, 1, 2, np.nan, np.nan, 3, 4], + index=list("aaabcdd"), + dtype=np.float64, + name="foo", ) tm.assert_series_equal(result, expected) From 920f63bedfd482cc90e9a2ec6244651da9e525fb Mon Sep 17 00:00:00 2001 From: Santhosh18 Date: Fri, 17 Jul 2020 17:13:35 +0530 Subject: [PATCH 7/8] Modified whasnew v1.1.0.rst --- doc/source/whatsnew/v1.1.0.rst | 37 ---------------------------------- 1 file changed, 37 deletions(-) diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index 2d2cd386c9e60..e56f8c9416235 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -748,43 +748,6 @@ Using :meth:`DataFrame.explode` and :meth:`Series.explode` would always return a B int64 dtype: object -.. _whatsnew_110.api.other: - -Other API changes -^^^^^^^^^^^^^^^^^ - -- :meth:`Series.describe` will now show distribution percentiles for ``datetime`` dtypes, statistics ``first`` and ``last`` - will now be ``min`` and ``max`` to match with numeric dtypes in :meth:`DataFrame.describe` (:issue:`30164`) -- Added :meth:`DataFrame.value_counts` (:issue:`5377`) -- :meth:`Groupby.groups` now returns an abbreviated representation when called on large dataframes (:issue:`1135`) -- ``loc`` lookups with an object-dtype :class:`Index` and an integer key will now raise ``KeyError`` instead of ``TypeError`` when key is missing (:issue:`31905`) -- Using a :func:`pandas.api.indexers.BaseIndexer` with ``count``, ``min``, ``max``, ``median``, ``skew``, ``cov``, ``corr`` will now return correct results for any monotonic :func:`pandas.api.indexers.BaseIndexer` descendant (:issue:`32865`) -- Added a :func:`pandas.api.indexers.FixedForwardWindowIndexer` class to support forward-looking windows during ``rolling`` operations. -- Added a :func:`pandas.api.indexers.NonFixedVariableWindowIndexer` class to support ``rolling`` operations with non-fixed offsets (:issue:`34994`) -- Added :class:`pandas.errors.InvalidIndexError` (:issue:`34570`). -- :meth:`DataFrame.swaplevels` now raises a ``TypeError`` if the axis is not a :class:`MultiIndex`. - Previously an ``AttributeError`` was raised (:issue:`31126`) -- :meth:`DataFrame.xs` now raises a ``TypeError`` if a ``level`` keyword is supplied and the axis is not a :class:`MultiIndex`. - Previously an ``AttributeError`` was raised (:issue:`33610`) -- :meth:`DataFrameGroupby.mean` and :meth:`SeriesGroupby.mean` (and similarly for :meth:`~DataFrameGroupby.median`, :meth:`~DataFrameGroupby.std` and :meth:`~DataFrameGroupby.var`) - now raise a ``TypeError`` if a not-accepted keyword argument is passed into it. - Previously a ``UnsupportedFunctionCall`` was raised (``AssertionError`` if ``min_count`` passed into :meth:`~DataFrameGroupby.median`) (:issue:`31485`) -- :meth:`DataFrame.at` and :meth:`Series.at` will raise a ``TypeError`` instead of a ``ValueError`` if an incompatible key is passed, and ``KeyError`` if a missing key is passed, matching the behavior of ``.loc[]`` (:issue:`31722`) -- Passing an integer dtype other than ``int64`` to ``np.array(period_index, dtype=...)`` will now raise ``TypeError`` instead of incorrectly using ``int64`` (:issue:`32255`) -- Passing an invalid ``fill_value`` to :meth:`Categorical.take` raises a ``ValueError`` instead of ``TypeError`` (:issue:`33660`) -- Combining a ``Categorical`` with integer categories and which contains missing values - with a float dtype column in operations such as :func:`concat` or :meth:`~DataFrame.append` - will now result in a float column instead of an object dtyped column (:issue:`33607`) -- :meth:`Series.to_timestamp` now raises a ``TypeError`` if the axis is not a :class:`PeriodIndex`. Previously an ``AttributeError`` was raised (:issue:`33327`) -- :meth:`Series.to_period` now raises a ``TypeError`` if the axis is not a :class:`DatetimeIndex`. Previously an ``AttributeError`` was raised (:issue:`33327`) -- :func: `pandas.api.dtypes.is_string_dtype` no longer incorrectly identifies categorical series as string. -- :func:`read_excel` no longer takes ``**kwds`` arguments. This means that passing in keyword ``chunksize`` now raises a ``TypeError`` - (previously raised a ``NotImplementedError``), while passing in keyword ``encoding`` now raises a ``TypeError`` (:issue:`34464`) -- :func: `merge` now checks ``suffixes`` parameter type to be ``tuple`` and raises ``TypeError``, whereas before a ``list`` or ``set`` were accepted and that the ``set`` could produce unexpected results (:issue:`33740`) -- :class:`Period` no longer accepts tuples for the ``freq`` argument (:issue:`34658`) -- :meth:`Series.interpolate` and :meth:`DataFrame.interpolate` now raises ValueError if ``limit_direction`` is 'forward' or 'both' and ``method`` is 'backfill' or 'bfill' or ``limit_direction`` is 'backward' or 'both' and ``method`` is 'pad' or 'ffill' (:issue:`34746`) - - Increased minimum versions for dependencies ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From f6144512d1385a29784e1f235132e1951268a31d Mon Sep 17 00:00:00 2001 From: Santhosh18 Date: Fri, 17 Jul 2020 18:39:34 +0530 Subject: [PATCH 8/8] Modified whatsnew v1.1.0.rst --- doc/source/whatsnew/v1.1.0.rst | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index e56f8c9416235..d5069c71d332b 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -740,13 +740,10 @@ Using :meth:`DataFrame.explode` and :meth:`Series.explode` would always return a *New behavior*: -.. ipython:: ipython +.. ipython:: python + + df.explode("A").dtypes - In [3]: df.explode("A").dtypes - Out[3]: - A int64 - B int64 - dtype: object Increased minimum versions for dependencies ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^