123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- import numpy as np
- import pytest
- from pandas import (
- DataFrame,
- Series,
- date_range,
- )
- import pandas._testing as tm
- from pandas.tests.copy_view.util import get_array
- # -----------------------------------------------------------------------------
- # Copy/view behaviour for accessing underlying array of Series/DataFrame
- @pytest.mark.parametrize(
- "method",
- [lambda ser: ser.values, lambda ser: np.asarray(ser)],
- ids=["values", "asarray"],
- )
- def test_series_values(using_copy_on_write, method):
- ser = Series([1, 2, 3], name="name")
- ser_orig = ser.copy()
- arr = method(ser)
- if using_copy_on_write:
- # .values still gives a view but is read-only
- assert np.shares_memory(arr, get_array(ser, "name"))
- assert arr.flags.writeable is False
- # mutating series through arr therefore doesn't work
- with pytest.raises(ValueError, match="read-only"):
- arr[0] = 0
- tm.assert_series_equal(ser, ser_orig)
- # mutating the series itself still works
- ser.iloc[0] = 0
- assert ser.values[0] == 0
- else:
- assert arr.flags.writeable is True
- arr[0] = 0
- assert ser.iloc[0] == 0
- @pytest.mark.parametrize(
- "method",
- [lambda df: df.values, lambda df: np.asarray(df)],
- ids=["values", "asarray"],
- )
- def test_dataframe_values(using_copy_on_write, using_array_manager, method):
- df = DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
- df_orig = df.copy()
- arr = method(df)
- if using_copy_on_write:
- # .values still gives a view but is read-only
- assert np.shares_memory(arr, get_array(df, "a"))
- assert arr.flags.writeable is False
- # mutating series through arr therefore doesn't work
- with pytest.raises(ValueError, match="read-only"):
- arr[0, 0] = 0
- tm.assert_frame_equal(df, df_orig)
- # mutating the series itself still works
- df.iloc[0, 0] = 0
- assert df.values[0, 0] == 0
- else:
- assert arr.flags.writeable is True
- arr[0, 0] = 0
- if not using_array_manager:
- assert df.iloc[0, 0] == 0
- else:
- tm.assert_frame_equal(df, df_orig)
- def test_series_to_numpy(using_copy_on_write):
- ser = Series([1, 2, 3], name="name")
- ser_orig = ser.copy()
- # default: copy=False, no dtype or NAs
- arr = ser.to_numpy()
- if using_copy_on_write:
- # to_numpy still gives a view but is read-only
- assert np.shares_memory(arr, get_array(ser, "name"))
- assert arr.flags.writeable is False
- # mutating series through arr therefore doesn't work
- with pytest.raises(ValueError, match="read-only"):
- arr[0] = 0
- tm.assert_series_equal(ser, ser_orig)
- # mutating the series itself still works
- ser.iloc[0] = 0
- assert ser.values[0] == 0
- else:
- assert arr.flags.writeable is True
- arr[0] = 0
- assert ser.iloc[0] == 0
- # specify copy=False gives a writeable array
- ser = Series([1, 2, 3], name="name")
- arr = ser.to_numpy(copy=True)
- assert not np.shares_memory(arr, get_array(ser, "name"))
- assert arr.flags.writeable is True
- # specifying a dtype that already causes a copy also gives a writeable array
- ser = Series([1, 2, 3], name="name")
- arr = ser.to_numpy(dtype="float64")
- assert not np.shares_memory(arr, get_array(ser, "name"))
- assert arr.flags.writeable is True
- @pytest.mark.parametrize("order", ["F", "C"])
- def test_ravel_read_only(using_copy_on_write, order):
- ser = Series([1, 2, 3])
- arr = ser.ravel(order=order)
- if using_copy_on_write:
- assert arr.flags.writeable is False
- assert np.shares_memory(get_array(ser), arr)
- def test_series_array_ea_dtypes(using_copy_on_write):
- ser = Series([1, 2, 3], dtype="Int64")
- arr = np.asarray(ser, dtype="int64")
- assert np.shares_memory(arr, get_array(ser))
- if using_copy_on_write:
- assert arr.flags.writeable is False
- else:
- assert arr.flags.writeable is True
- arr = np.asarray(ser)
- assert not np.shares_memory(arr, get_array(ser))
- assert arr.flags.writeable is True
- def test_dataframe_array_ea_dtypes(using_copy_on_write):
- df = DataFrame({"a": [1, 2, 3]}, dtype="Int64")
- arr = np.asarray(df, dtype="int64")
- # TODO: This should be able to share memory, but we are roundtripping
- # through object
- assert not np.shares_memory(arr, get_array(df, "a"))
- assert arr.flags.writeable is True
- arr = np.asarray(df)
- if using_copy_on_write:
- # TODO(CoW): This should be True
- assert arr.flags.writeable is False
- else:
- assert arr.flags.writeable is True
- def test_dataframe_array_string_dtype(using_copy_on_write, using_array_manager):
- df = DataFrame({"a": ["a", "b"]}, dtype="string")
- arr = np.asarray(df)
- if not using_array_manager:
- assert np.shares_memory(arr, get_array(df, "a"))
- if using_copy_on_write:
- assert arr.flags.writeable is False
- else:
- assert arr.flags.writeable is True
- def test_dataframe_multiple_numpy_dtypes():
- df = DataFrame({"a": [1, 2, 3], "b": 1.5})
- arr = np.asarray(df)
- assert not np.shares_memory(arr, get_array(df, "a"))
- assert arr.flags.writeable is True
- def test_values_is_ea(using_copy_on_write):
- df = DataFrame({"a": date_range("2012-01-01", periods=3)})
- arr = np.asarray(df)
- if using_copy_on_write:
- assert arr.flags.writeable is False
- else:
- assert arr.flags.writeable is True
- def test_empty_dataframe():
- df = DataFrame()
- arr = np.asarray(df)
- assert arr.flags.writeable is True
|