Skip to content

Commit 0cc64a0

Browse files
authored
Drop conflicted coordinate when assignment. (#2087)
* Drop conflicted coordinate when assignment. * flake8 * Python 2 support. Avoid overwrite variables to be assigned. * More pythonic
1 parent 39bd207 commit 0cc64a0

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed

doc/whats-new.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ Enhancements
4040
Bug fixes
4141
~~~~~~~~~
4242

43+
- When assigning a :py:class:`DataArray` to :py:class:`Dataset`, any conflicted
44+
non-dimensional coordinates of the DataArray are now dropped.
45+
(:issue:`2068`)
46+
By `Keisuke Fujii <https://github.com/fujiisoup>`_.
4347
- Better error handling in ``open_mfdataset`` (:issue:`2077`).
4448
By `Stephan Hoyer <https://github.com/shoyer>`_.
4549

xarray/core/merge.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,21 @@ def dataset_merge_method(dataset, other, overwrite_vars, compat, join):
547547

548548

549549
def dataset_update_method(dataset, other):
550-
"""Guts of the Dataset.update method"""
550+
"""Guts of the Dataset.update method
551+
552+
This drops a duplicated coordinates from `other` (GH:2068)
553+
"""
554+
from .dataset import Dataset
555+
from .dataarray import DataArray
556+
557+
other = other.copy()
558+
for k, obj in other.items():
559+
if isinstance(obj, (Dataset, DataArray)):
560+
# drop duplicated coordinates
561+
coord_names = [c for c in obj.coords
562+
if c not in obj.dims and c in dataset.coords]
563+
if coord_names:
564+
other[k] = obj.drop(*coord_names)
565+
551566
return merge_core([dataset, other], priority_arg=1,
552567
indexes=dataset.indexes)

xarray/tests/test_dataset.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2327,6 +2327,45 @@ def test_setitem_auto_align(self):
23272327
expected = Dataset({'x': ('y', [4, 5, 6])}, {'y': range(3)})
23282328
assert_identical(ds, expected)
23292329

2330+
def test_setitem_with_coords(self):
2331+
# Regression test for GH:2068
2332+
ds = create_test_data()
2333+
2334+
other = DataArray(np.arange(10), dims='dim3',
2335+
coords={'numbers': ('dim3', np.arange(10))})
2336+
expected = ds.copy()
2337+
expected['var3'] = other.drop('numbers')
2338+
actual = ds.copy()
2339+
actual['var3'] = other
2340+
assert_identical(expected, actual)
2341+
assert 'numbers' in other # should not change other
2342+
2343+
# with alignment
2344+
other = ds['var3'].isel(dim3=slice(1, -1))
2345+
other['numbers'] = ('dim3', np.arange(8))
2346+
actual = ds.copy()
2347+
actual['var3'] = other
2348+
assert 'numbers' in other # should not change other
2349+
expected = ds.copy()
2350+
expected['var3'] = ds['var3'].isel(dim3=slice(1, -1))
2351+
assert_identical(expected, actual)
2352+
2353+
# with non-duplicate coords
2354+
other = ds['var3'].isel(dim3=slice(1, -1))
2355+
other['numbers'] = ('dim3', np.arange(8))
2356+
other['position'] = ('dim3', np.arange(8))
2357+
actual = ds.copy()
2358+
actual['var3'] = other
2359+
assert 'position' in actual
2360+
assert 'position' in other
2361+
2362+
# assigning a coordinate-only dataarray
2363+
actual = ds.copy()
2364+
other = actual['numbers']
2365+
other[0] = 10
2366+
actual['numbers'] = other
2367+
assert actual['numbers'][0] == 10
2368+
23302369
def test_setitem_align_new_indexes(self):
23312370
ds = Dataset({'foo': ('x', [1, 2, 3])}, {'x': [0, 1, 2]})
23322371
ds['bar'] = DataArray([2, 3, 4], [('x', [1, 2, 3])])

0 commit comments

Comments
 (0)