From 99e4a77b1646728c57a15690d7c514f48980d82e Mon Sep 17 00:00:00 2001 From: Patrick Hoefler Date: Mon, 27 Feb 2023 12:29:01 +0100 Subject: [PATCH 1/2] CLN: Ensure that setitem ops don't coerce values --- pandas/core/frame.py | 16 +++++++++++----- pandas/tests/frame/indexing/test_insert.py | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index d80c80fa5d0ab..641062fca42d1 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4757,6 +4757,14 @@ def insert( if not isinstance(loc, int): raise TypeError("loc must be int") + if isinstance(value, DataFrame) and len(value.columns) > 1: + raise ValueError( + f"Expected a one-dimensional object, got a DataFrame with " + f"{len(value.columns)} instead." + ) + elif isinstance(value, DataFrame): + value = value.iloc[:, 0] + value = self._sanitize_column(value) self._mgr.insert(loc, column, value) @@ -4843,11 +4851,9 @@ def _sanitize_column(self, value) -> ArrayLike: """ self._ensure_valid_index(value) - # We can get there through isetitem with a DataFrame - # or through loc single_block_path - if isinstance(value, DataFrame): - return _reindex_for_setitem(value, self.index) - elif is_dict_like(value): + # Using a DataFrame would mean coercing values to one dtype + assert not isinstance(value, DataFrame) + if is_dict_like(value): return _reindex_for_setitem(Series(value), self.index) if is_list_like(value): diff --git a/pandas/tests/frame/indexing/test_insert.py b/pandas/tests/frame/indexing/test_insert.py index d084f841f9e19..98a72d52d4e06 100644 --- a/pandas/tests/frame/indexing/test_insert.py +++ b/pandas/tests/frame/indexing/test_insert.py @@ -100,6 +100,6 @@ def test_insert_frame(self): # GH#42403 df = DataFrame({"col1": [1, 2], "col2": [3, 4]}) - msg = r"Expected a 1D array, got an array with shape \(2, 2\)" + msg = "Expected a one-dimensional object, got a DataFrame with 2 instead." with pytest.raises(ValueError, match=msg): df.insert(1, "newcol", df) From 3365a61feea1e96eae8de9e76ccbcf21422e14ff Mon Sep 17 00:00:00 2001 From: Patrick Hoefler Date: Mon, 27 Feb 2023 20:20:18 +0100 Subject: [PATCH 2/2] Fix message --- pandas/core/frame.py | 2 +- pandas/tests/frame/indexing/test_insert.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 641062fca42d1..dbbe2c0751f3a 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4760,7 +4760,7 @@ def insert( if isinstance(value, DataFrame) and len(value.columns) > 1: raise ValueError( f"Expected a one-dimensional object, got a DataFrame with " - f"{len(value.columns)} instead." + f"{len(value.columns)} columns instead." ) elif isinstance(value, DataFrame): value = value.iloc[:, 0] diff --git a/pandas/tests/frame/indexing/test_insert.py b/pandas/tests/frame/indexing/test_insert.py index 98a72d52d4e06..5d0a51ea0d462 100644 --- a/pandas/tests/frame/indexing/test_insert.py +++ b/pandas/tests/frame/indexing/test_insert.py @@ -100,6 +100,8 @@ def test_insert_frame(self): # GH#42403 df = DataFrame({"col1": [1, 2], "col2": [3, 4]}) - msg = "Expected a one-dimensional object, got a DataFrame with 2 instead." + msg = ( + "Expected a one-dimensional object, got a DataFrame with 2 columns instead." + ) with pytest.raises(ValueError, match=msg): df.insert(1, "newcol", df)