From c7b9c09c521e3e7eb369f0bb3c9710f7c7bd38b5 Mon Sep 17 00:00:00 2001 From: Matthew Zeitlin Date: Tue, 23 Mar 2021 11:43:06 -0400 Subject: [PATCH 1/7] REGR: where not copying on noop --- pandas/core/internals/blocks.py | 3 ++- pandas/tests/frame/indexing/test_where.py | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index c13eb3f109354..b0a6c96892e8b 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1327,7 +1327,8 @@ def where(self, other, cond, errors="raise") -> List[Block]: if noop: # TODO: avoid the downcasting at the end in this case? - result = values + # GH-#39595: Always return a copy + result = values.copy() else: # see if we can operate on the entire block, or need item-by-item # or if we are a single block (ndim == 1) diff --git a/pandas/tests/frame/indexing/test_where.py b/pandas/tests/frame/indexing/test_where.py index bc84d7c70b01c..f1cfdaa056289 100644 --- a/pandas/tests/frame/indexing/test_where.py +++ b/pandas/tests/frame/indexing/test_where.py @@ -692,3 +692,13 @@ def test_where_try_cast_deprecated(frame_or_series): with tm.assert_produces_warning(FutureWarning): # try_cast keyword deprecated obj.where(mask, -1, try_cast=False) + + +def test_where_copies_with_noop(frame_or_series): + result = frame_or_series([1, 2, 3, 4]) + expected = result.copy() + col = result[0] if frame_or_series is DataFrame else result + + where_res = result.where(col < 5) + where_res *= 2 + tm.assert_equal(result, expected) From 558490529cab99e717dba236068864d40100188f Mon Sep 17 00:00:00 2001 From: Matthew Zeitlin Date: Tue, 23 Mar 2021 11:43:53 -0400 Subject: [PATCH 2/7] Add test --- pandas/tests/frame/indexing/test_where.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/frame/indexing/test_where.py b/pandas/tests/frame/indexing/test_where.py index f1cfdaa056289..f620368ac896c 100644 --- a/pandas/tests/frame/indexing/test_where.py +++ b/pandas/tests/frame/indexing/test_where.py @@ -698,7 +698,7 @@ def test_where_copies_with_noop(frame_or_series): result = frame_or_series([1, 2, 3, 4]) expected = result.copy() col = result[0] if frame_or_series is DataFrame else result - + where_res = result.where(col < 5) where_res *= 2 tm.assert_equal(result, expected) From f39021bd8ca9217db884f1ce3e1eb036ab082a84 Mon Sep 17 00:00:00 2001 From: Matthew Zeitlin Date: Tue, 23 Mar 2021 11:46:04 -0400 Subject: [PATCH 3/7] precommit fixup --- pandas/tests/frame/indexing/test_where.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/tests/frame/indexing/test_where.py b/pandas/tests/frame/indexing/test_where.py index f620368ac896c..5f945e41a1692 100644 --- a/pandas/tests/frame/indexing/test_where.py +++ b/pandas/tests/frame/indexing/test_where.py @@ -701,4 +701,5 @@ def test_where_copies_with_noop(frame_or_series): where_res = result.where(col < 5) where_res *= 2 + tm.assert_equal(result, expected) From 5f1392dfb06b531d034941eef7f1bde6066d4685 Mon Sep 17 00:00:00 2001 From: Matthew Zeitlin Date: Tue, 23 Mar 2021 11:48:58 -0400 Subject: [PATCH 4/7] Add whatsnew --- doc/source/whatsnew/v1.2.4.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.2.4.rst b/doc/source/whatsnew/v1.2.4.rst index c7bc337239faf..07ad9c3be34c6 100644 --- a/doc/source/whatsnew/v1.2.4.rst +++ b/doc/source/whatsnew/v1.2.4.rst @@ -17,7 +17,7 @@ Fixed regressions - Fixed regression in :meth:`DataFrame.sum` when ``min_count`` greater than the :class:`DataFrame` shape was passed resulted in a ``ValueError`` (:issue:`39738`) - Fixed regression in :meth:`DataFrame.to_json` raising ``AttributeError`` when run on PyPy (:issue:`39837`) -- +- Fixed regression :meth:`DataFrame.where` not returning a copy in the case of an all .. --------------------------------------------------------------------------- From b3ff39f5c39b7205e4e8dbcc54ec927ff8db1234 Mon Sep 17 00:00:00 2001 From: Matthew Zeitlin Date: Tue, 23 Mar 2021 11:52:28 -0400 Subject: [PATCH 5/7] Add an additional test case --- doc/source/whatsnew/v1.2.4.rst | 3 ++- pandas/tests/frame/indexing/test_where.py | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.2.4.rst b/doc/source/whatsnew/v1.2.4.rst index 07ad9c3be34c6..c398acca9c2b6 100644 --- a/doc/source/whatsnew/v1.2.4.rst +++ b/doc/source/whatsnew/v1.2.4.rst @@ -17,7 +17,8 @@ Fixed regressions - Fixed regression in :meth:`DataFrame.sum` when ``min_count`` greater than the :class:`DataFrame` shape was passed resulted in a ``ValueError`` (:issue:`39738`) - Fixed regression in :meth:`DataFrame.to_json` raising ``AttributeError`` when run on PyPy (:issue:`39837`) -- Fixed regression :meth:`DataFrame.where` not returning a copy in the case of an all +- Fixed regression :meth:`DataFrame.where` not returning a copy in the case of an all True condition (:issue:`39595`) +- .. --------------------------------------------------------------------------- diff --git a/pandas/tests/frame/indexing/test_where.py b/pandas/tests/frame/indexing/test_where.py index 5f945e41a1692..574fa46d10f67 100644 --- a/pandas/tests/frame/indexing/test_where.py +++ b/pandas/tests/frame/indexing/test_where.py @@ -695,6 +695,7 @@ def test_where_try_cast_deprecated(frame_or_series): def test_where_copies_with_noop(frame_or_series): + # GH-39595 result = frame_or_series([1, 2, 3, 4]) expected = result.copy() col = result[0] if frame_or_series is DataFrame else result @@ -703,3 +704,8 @@ def test_where_copies_with_noop(frame_or_series): where_res *= 2 tm.assert_equal(result, expected) + + where_res = result.where(col > 5, [1, 2, 3, 4]) + where_res *= 2 + + tm.assert_equal(result, expected) From 8f307bada31fd2937c948402dd5d81975c6be8bf Mon Sep 17 00:00:00 2001 From: Matthew Zeitlin Date: Tue, 23 Mar 2021 12:11:10 -0400 Subject: [PATCH 6/7] Fix comment --- pandas/core/internals/blocks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index b0a6c96892e8b..79cf31c5caaac 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1327,7 +1327,7 @@ def where(self, other, cond, errors="raise") -> List[Block]: if noop: # TODO: avoid the downcasting at the end in this case? - # GH-#39595: Always return a copy + # GH-39595: Always return a copy result = values.copy() else: # see if we can operate on the entire block, or need item-by-item From 4a17b59a8b0e4f797dfff5c1e756d1cfde21ba86 Mon Sep 17 00:00:00 2001 From: Matthew Zeitlin Date: Tue, 23 Mar 2021 12:12:38 -0400 Subject: [PATCH 7/7] Fix typo --- doc/source/whatsnew/v1.2.4.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.2.4.rst b/doc/source/whatsnew/v1.2.4.rst index c398acca9c2b6..45d131327630e 100644 --- a/doc/source/whatsnew/v1.2.4.rst +++ b/doc/source/whatsnew/v1.2.4.rst @@ -17,7 +17,7 @@ Fixed regressions - Fixed regression in :meth:`DataFrame.sum` when ``min_count`` greater than the :class:`DataFrame` shape was passed resulted in a ``ValueError`` (:issue:`39738`) - Fixed regression in :meth:`DataFrame.to_json` raising ``AttributeError`` when run on PyPy (:issue:`39837`) -- Fixed regression :meth:`DataFrame.where` not returning a copy in the case of an all True condition (:issue:`39595`) +- Fixed regression in :meth:`DataFrame.where` not returning a copy in the case of an all True condition (:issue:`39595`) - .. ---------------------------------------------------------------------------