Skip to content

Commit c04234d

Browse files
pletchmmax-sixty
authored andcommitted
BUGFIX: deep-copy wasn't copying coords, bug fixed within IndexVariable (#2936)
1 parent 5aaa654 commit c04234d

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
@@ -35,6 +35,8 @@ Bug fixes
3535
By `Mayeul d'Avezac <https://github.com/mdavezac>`_.
3636
- Return correct count for scalar datetime64 arrays (:issue:`2770`)
3737
By `Dan Nowacki <https://github.com/dnowacki-usgs>`_.
38+
- A deep copy deep-copies the coords (:issue:`1463`)
39+
By `Martin Pletcher <https://github.com/pletchm>`_.
3840

3941
.. _whats-new.0.12.1:
4042

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
@@ -3321,6 +3321,28 @@ def test_copy_with_data(self):
33213321
expected.data = new_data
33223322
assert_identical(expected, actual)
33233323

3324+
@pytest.mark.parametrize('deep, expected_orig', [
3325+
[True,
3326+
xr.DataArray(xr.IndexVariable('a', np.array([1, 2])),
3327+
coords={'a': [1, 2]}, dims=['a'])],
3328+
[False,
3329+
xr.DataArray(xr.IndexVariable('a', np.array([999, 2])),
3330+
coords={'a': [999, 2]}, dims=['a'])]])
3331+
def test_copy_coords(self, deep, expected_orig):
3332+
da = xr.DataArray(
3333+
np.ones([2, 2, 2]),
3334+
coords={'a': [1, 2], 'b': ['x', 'y'], 'c': [0, 1]},
3335+
dims=['a', 'b', 'c'])
3336+
da_cp = da.copy(deep)
3337+
da_cp['a'].data[0] = 999
3338+
3339+
expected_cp = xr.DataArray(
3340+
xr.IndexVariable('a', np.array([999, 2])),
3341+
coords={'a': [999, 2]}, dims=['a'])
3342+
assert_identical(da_cp['a'], expected_cp)
3343+
3344+
assert_identical(da['a'], expected_orig)
3345+
33243346
def test_real_and_imag(self):
33253347
array = DataArray(1 + 2j)
33263348
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
@@ -1971,6 +1971,29 @@ def test_copy_with_data(self):
19711971
expected[k].data = v
19721972
assert_identical(expected, actual)
19731973

1974+
@pytest.mark.parametrize('deep, expected_orig', [
1975+
[True,
1976+
xr.DataArray(xr.IndexVariable('a', np.array([1, 2])),
1977+
coords={'a': [1, 2]}, dims=['a'])],
1978+
[False,
1979+
xr.DataArray(xr.IndexVariable('a', np.array([999, 2])),
1980+
coords={'a': [999, 2]}, dims=['a'])]])
1981+
def test_copy_coords(self, deep, expected_orig):
1982+
ds = xr.DataArray(
1983+
np.ones([2, 2, 2]),
1984+
coords={'a': [1, 2], 'b': ['x', 'y'], 'c': [0, 1]},
1985+
dims=['a', 'b', 'c'],
1986+
name='value').to_dataset()
1987+
ds_cp = ds.copy(deep=deep)
1988+
ds_cp.coords['a'].data[0] = 999
1989+
1990+
expected_cp = xr.DataArray(
1991+
xr.IndexVariable('a', np.array([999, 2])),
1992+
coords={'a': [999, 2]}, dims=['a'])
1993+
assert_identical(ds_cp.coords['a'], expected_cp)
1994+
1995+
assert_identical(ds.coords['a'], expected_orig)
1996+
19741997
def test_copy_with_data_errors(self):
19751998
orig = create_test_data()
19761999
new_var1 = np.arange(orig['var1'].size).reshape(orig['var1'].shape)

0 commit comments

Comments
 (0)