diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index cdc9cbe0d7261..a8f545c7be05f 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -197,6 +197,9 @@ Copy-on-Write improvements behavior when the NumPy array is modified after creation of the :class:`DataFrame`. +- The :meth:`DataFrame.from_records` will now respect Copy-on-Write when called + with a :class:`DataFrame`. + - Trying to set values using chained assignment (for example, ``df["a"][1:3] = 0``) will now always raise an warning when Copy-on-Write is enabled. In this mode, chained assignment can never work because we are always setting into a temporary diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 881993a6a4f5d..e7b48b83ab22e 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -2209,7 +2209,7 @@ def from_records( data = data.set_index(index) if exclude is not None: data = data.drop(columns=exclude) - return data + return data.copy(deep=False) result_index = None diff --git a/pandas/tests/copy_view/test_constructors.py b/pandas/tests/copy_view/test_constructors.py index 8ceb3cd7d2d2b..cc10ca7fa483f 100644 --- a/pandas/tests/copy_view/test_constructors.py +++ b/pandas/tests/copy_view/test_constructors.py @@ -231,3 +231,18 @@ def test_frame_from_numpy_array(using_copy_on_write, copy, using_array_manager): assert not np.shares_memory(get_array(df, 0), arr) else: assert np.shares_memory(get_array(df, 0), arr) + + +def test_dataframe_from_records_with_dataframe(using_copy_on_write): + df = DataFrame({"a": [1, 2, 3]}) + df_orig = df.copy() + with tm.assert_produces_warning(FutureWarning): + df2 = DataFrame.from_records(df) + if using_copy_on_write: + assert not df._mgr._has_no_reference(0) + assert np.shares_memory(get_array(df, "a"), get_array(df2, "a")) + df2.iloc[0, 0] = 100 + if using_copy_on_write: + tm.assert_frame_equal(df, df_orig) + else: + tm.assert_frame_equal(df, df2)