Skip to content

Commit 3d96498

Browse files
committed
BUGFIX: deep-copy wasn't copying coords, bug fixed within IndexVariable.copy method
Update whats-new.rst to include this change in the bugfix section
1 parent 995bb4b commit 3d96498

File tree

4 files changed

+57
-2
lines changed

4 files changed

+57
-2
lines changed

doc/whats-new.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ Bug fixes
3232
By `Mayeul d'Avezac <https://github.com/mdavezac>`_.
3333
- Return correct count for scalar datetime64 arrays (:issue:`2770`)
3434
By `Dan Nowacki <https://github.com/dnowacki-usgs>`_.
35+
- A deep copy deep-copies the coords (:issue:`1463`)
36+
By `Martin Pletcher <https://github.com/pletchm>`_.
3537

3638
.. _whats-new.0.12.1:
3739

xarray/core/variable.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1906,7 +1906,8 @@ def copy(self, deep=True, data=None):
19061906
Parameters
19071907
----------
19081908
deep : bool, optional
1909-
Deep is always ignored.
1909+
Deep is ignored when data is given. Whether the data array is
1910+
loaded into memory and copied onto the new object. Default is True.
19101911
data : array_like, optional
19111912
Data to use in the new object. Must have same shape as original.
19121913
@@ -1917,7 +1918,14 @@ def copy(self, deep=True, data=None):
19171918
data copied from original.
19181919
"""
19191920
if data is None:
1920-
data = self._data
1921+
if deep:
1922+
# self._data should be a `PandasIndexAdapter` instance at this
1923+
# point, which doesn't have a copy method, so make a deep copy
1924+
# of the underlying `pandas.MultiIndex` and create a new
1925+
# `PandasIndexAdapter` instance with it.
1926+
data = PandasIndexAdapter(self._data.array.copy(deep=True))
1927+
else:
1928+
data = self._data
19211929
else:
19221930
data = as_compatible_data(data)
19231931
if self.shape != data.shape:

xarray/tests/test_dataarray.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3297,6 +3297,28 @@ def test_copy_with_data(self):
32973297
expected.data = new_data
32983298
assert_identical(expected, actual)
32993299

3300+
@pytest.mark.parametrize('deep, expected_orig', [
3301+
[True,
3302+
xr.DataArray(xr.IndexVariable('a', np.array([1, 2])),
3303+
coords={'a': [1, 2]}, dims=['a'])],
3304+
[False,
3305+
xr.DataArray(xr.IndexVariable('a', np.array([999, 2])),
3306+
coords={'a': [999, 2]}, dims=['a'])]])
3307+
def test_copy_coords(self, deep, expected_orig):
3308+
da = xr.DataArray(
3309+
np.ones([2, 2, 2]),
3310+
coords={'a': [1, 2], 'b': ['x', 'y'], 'c': [0, 1]},
3311+
dims=['a', 'b', 'c'])
3312+
da_cp = da.copy(deep)
3313+
da_cp['a'].data[0] = 999
3314+
3315+
expected_cp = xr.DataArray(
3316+
xr.IndexVariable('a', np.array([999, 2])),
3317+
coords={'a': [999, 2]}, dims=['a'])
3318+
assert_identical(da_cp['a'], expected_cp)
3319+
3320+
assert_identical(da['a'], expected_orig)
3321+
33003322
def test_real_and_imag(self):
33013323
array = DataArray(1 + 2j)
33023324
assert_identical(array.real, DataArray(1))

xarray/tests/test_dataset.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1923,6 +1923,29 @@ def test_copy_with_data(self):
19231923
expected[k].data = v
19241924
assert_identical(expected, actual)
19251925

1926+
@pytest.mark.parametrize('deep, expected_orig', [
1927+
[True,
1928+
xr.DataArray(xr.IndexVariable('a', np.array([1, 2])),
1929+
coords={'a': [1, 2]}, dims=['a'])],
1930+
[False,
1931+
xr.DataArray(xr.IndexVariable('a', np.array([999, 2])),
1932+
coords={'a': [999, 2]}, dims=['a'])]])
1933+
def test_copy_coords(self, deep, expected_orig):
1934+
ds = xr.DataArray(
1935+
np.ones([2, 2, 2]),
1936+
coords={'a': [1, 2], 'b': ['x', 'y'], 'c': [0, 1]},
1937+
dims=['a', 'b', 'c'],
1938+
name='value').to_dataset()
1939+
ds_cp = ds.copy(deep=deep)
1940+
ds_cp.coords['a'].data[0] = 999
1941+
1942+
expected_cp = xr.DataArray(
1943+
xr.IndexVariable('a', np.array([999, 2])),
1944+
coords={'a': [999, 2]}, dims=['a'])
1945+
assert_identical(ds_cp.coords['a'], expected_cp)
1946+
1947+
assert_identical(ds.coords['a'], expected_orig)
1948+
19261949
def test_copy_with_data_errors(self):
19271950
orig = create_test_data()
19281951
new_var1 = np.arange(orig['var1'].size).reshape(orig['var1'].shape)

0 commit comments

Comments
 (0)