diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index db69f43e92518..9d5fcf12ac3e3 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -191,7 +191,8 @@ Copy-on-Write improvements of those Series objects for the columns of the DataFrame (:issue:`50777`) - The :class:`DataFrame` constructor, when constructing a DataFrame from a - :class:`Series` and specifying ``copy=False``, will now respect Copy-on-Write. + :class:`Series` or :class:`Index` and specifying ``copy=False``, will + now respect Copy-on-Write. - The :class:`DataFrame` constructor, when constructing from a NumPy array, will now copy the array by default to avoid mutating the :class:`DataFrame` diff --git a/pandas/core/internals/construction.py b/pandas/core/internals/construction.py index 48731c5ff85f4..5fa7901cf85e9 100644 --- a/pandas/core/internals/construction.py +++ b/pandas/core/internals/construction.py @@ -292,7 +292,7 @@ def ndarray_to_mgr( if values.ndim == 1: values = values.reshape(-1, 1) - elif isinstance(values, ABCSeries): + elif isinstance(values, (ABCSeries, Index)): if not copy_on_sanitize and ( dtype is None or astype_is_view(values.dtype, dtype) ): @@ -305,7 +305,7 @@ def ndarray_to_mgr( values = _ensure_2d(values) - elif isinstance(values, (np.ndarray, ExtensionArray, Index)): + elif isinstance(values, (np.ndarray, ExtensionArray)): # drop subclass info _copy = ( copy_on_sanitize diff --git a/pandas/tests/copy_view/test_constructors.py b/pandas/tests/copy_view/test_constructors.py index 2e00352dda7ae..6244452541e0b 100644 --- a/pandas/tests/copy_view/test_constructors.py +++ b/pandas/tests/copy_view/test_constructors.py @@ -228,26 +228,28 @@ def test_dataframe_from_dict_of_series_with_reindex(dtype): assert np.shares_memory(arr_before, arr_after) +@pytest.mark.parametrize("cons", [Series, Index]) @pytest.mark.parametrize( "data, dtype", [([1, 2], None), ([1, 2], "int64"), (["a", "b"], None)] ) -def test_dataframe_from_series(using_copy_on_write, data, dtype): - ser = Series(data, dtype=dtype) - ser_orig = ser.copy() - df = DataFrame(ser, dtype=dtype) - assert np.shares_memory(get_array(ser), get_array(df, 0)) +def test_dataframe_from_series_or_index(using_copy_on_write, data, dtype, cons): + obj = cons(data, dtype=dtype) + obj_orig = obj.copy() + df = DataFrame(obj, dtype=dtype) + assert np.shares_memory(get_array(obj), get_array(df, 0)) if using_copy_on_write: assert not df._mgr._has_no_reference(0) df.iloc[0, 0] = data[-1] if using_copy_on_write: - tm.assert_series_equal(ser, ser_orig) + tm.assert_equal(obj, obj_orig) -def test_dataframe_from_series_different_dtype(using_copy_on_write): - ser = Series([1, 2], dtype="int64") - df = DataFrame(ser, dtype="int32") - assert not np.shares_memory(get_array(ser), get_array(df, 0)) +@pytest.mark.parametrize("cons", [Series, Index]) +def test_dataframe_from_series_or_index_different_dtype(using_copy_on_write, cons): + obj = cons([1, 2], dtype="int64") + df = DataFrame(obj, dtype="int32") + assert not np.shares_memory(get_array(obj), get_array(df, 0)) if using_copy_on_write: assert df._mgr._has_no_reference(0)