diff --git a/doc/source/whatsnew/v2.0.3.rst b/doc/source/whatsnew/v2.0.3.rst index 89c64b02e0cb5..67f31c45c0d7a 100644 --- a/doc/source/whatsnew/v2.0.3.rst +++ b/doc/source/whatsnew/v2.0.3.rst @@ -14,7 +14,7 @@ including other versions of pandas. Fixed regressions ~~~~~~~~~~~~~~~~~ - Fixed performance regression in merging on datetime-like columns (:issue:`53231`) -- +- Fixed regression in :meth:`DataFrame.loc` rows are not inserted into DataFrame from lists of one element (:issue:`52825`) .. --------------------------------------------------------------------------- .. _whatsnew_203.bug_fixes: diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 38bf6c34bf9c9..505e07f8baa70 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -2024,10 +2024,18 @@ def _setitem_single_column(self, loc: int, value, plane_indexer) -> None: is_null_setter = com.is_empty_slice(pi) or is_array_like(pi) and len(pi) == 0 + is_empty_df_setter = com.is_null_slice(pi) and len(self.obj) == 0 + if is_null_setter: # no-op, don't cast dtype later return + elif is_empty_df_setter: + # If we're setting a column to an empty df with null slice, + # we shouldn't do it inplace. + # GH#52825 + self.obj.isetitem(loc, value) + elif is_full_setter: try: self.obj._mgr.column_setitem( diff --git a/pandas/tests/indexing/test_indexing.py b/pandas/tests/indexing/test_indexing.py index 21036598f46df..6e829309e1630 100644 --- a/pandas/tests/indexing/test_indexing.py +++ b/pandas/tests/indexing/test_indexing.py @@ -631,6 +631,17 @@ def test_index_type_coercion(self, indexer): indexer(s2)["0"] = 0 assert is_object_dtype(s2.index) + def test_setitem_one_element_list(self): + # GH#52825 + x_values = ["x_value"] + y_values = ["y_value"] + df = DataFrame(columns=["x", "y"]) + df.loc[:, "x"] = x_values + df.loc[:, "y"] = y_values + + expected = DataFrame({"x": ["x_value"], "y": ["y_value"]}) + tm.assert_frame_equal(df, expected) + class TestMisc: def test_float_index_to_mixed(self): diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index 4017a0e3a2f80..ec7abc659262a 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -614,18 +614,16 @@ def test_loc_setitem_consistency_single_row(self): def test_loc_setitem_consistency_empty(self): # empty (essentially noops) - # before the enforcement of #45333 in 2.0, the loc.setitem here would - # change the dtype of df.x to int64 + # the loc.setitem here changes the dtype of df.x to int64 expected = DataFrame(columns=["x", "y"]) + expected["x"] = expected["x"].astype(np.int64) df = DataFrame(columns=["x", "y"]) with tm.assert_produces_warning(None): df.loc[:, "x"] = 1 tm.assert_frame_equal(df, expected) - # setting with setitem swaps in a new array, so changes the dtype df = DataFrame(columns=["x", "y"]) df["x"] = 1 - expected["x"] = expected["x"].astype(np.int64) tm.assert_frame_equal(df, expected) def test_loc_setitem_consistency_slice_column_len(self):