Skip to content

Commit aaf3738

Browse files
dcherianTomNicholas
authored andcommitted
concat keeps attrs from first variable. (#3637)
* concat keep attrs from first variable. Fixes #2060 Fixes #2575
1 parent 3cbc459 commit aaf3738

File tree

5 files changed

+25
-10
lines changed

5 files changed

+25
-10
lines changed

doc/whats-new.rst

+3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ Breaking changes
2525

2626
New Features
2727
~~~~~~~~~~~~
28+
- :py:func:`xarray.concat` now preserves attributes from the first Variable.
29+
(:issue:`2575`, :issue:`2060`, :issue:`1614`)
30+
By `Deepak Cherian <https://github.com/dcherian>`_.
2831
- :py:meth:`Dataset.quantile`, :py:meth:`DataArray.quantile` and ``GroupBy.quantile``
2932
now work with dask Variables.
3033
By `Deepak Cherian <https://github.com/dcherian>`_.

xarray/core/concat.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,14 @@ def concat(
9393
those of the first object with that dimension. Indexes for the same
9494
dimension must have the same size in all objects.
9595
96-
indexers, mode, concat_over : deprecated
97-
9896
Returns
9997
-------
10098
concatenated : type of objs
10199
100+
Notes
101+
-----
102+
Each concatenated Variable preserves corresponding ``attrs`` from the first element of ``objs``.
103+
102104
See also
103105
--------
104106
merge

xarray/core/variable.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1625,8 +1625,9 @@ def concat(cls, variables, dim="concat_dim", positions=None, shortcut=False):
16251625
if not shortcut:
16261626
for var in variables:
16271627
if var.dims != first_var.dims:
1628-
raise ValueError("inconsistent dimensions")
1629-
utils.remove_incompatible_items(attrs, var.attrs)
1628+
raise ValueError(
1629+
f"Variable has dimensions {list(var.dims)} but first Variable has dimensions {list(first_var.dims)}"
1630+
)
16301631

16311632
return cls(dims, data, attrs, encoding)
16321633

xarray/tests/test_concat.py

+13
Original file line numberDiff line numberDiff line change
@@ -462,3 +462,16 @@ def test_concat_join_kwarg(self):
462462
for join in expected:
463463
actual = concat([ds1, ds2], join=join, dim="x")
464464
assert_equal(actual, expected[join].to_array())
465+
466+
467+
@pytest.mark.parametrize("attr1", ({"a": {"meta": [10, 20, 30]}}, {"a": [1, 2, 3]}, {}))
468+
@pytest.mark.parametrize("attr2", ({"a": [1, 2, 3]}, {}))
469+
def test_concat_attrs_first_variable(attr1, attr2):
470+
471+
arrs = [
472+
DataArray([[1], [2]], dims=["x", "y"], attrs=attr1),
473+
DataArray([[3], [4]], dims=["x", "y"], attrs=attr2),
474+
]
475+
476+
concat_attrs = concat(arrs, "y").attrs
477+
assert concat_attrs == attr1

xarray/tests/test_variable.py

+2-6
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ def test_concat(self):
432432
assert_identical(
433433
Variable(["b", "a"], np.array([x, y])), Variable.concat((v, w), "b")
434434
)
435-
with raises_regex(ValueError, "inconsistent dimensions"):
435+
with raises_regex(ValueError, "Variable has dimensions"):
436436
Variable.concat([v, Variable(["c"], y)], "b")
437437
# test indexers
438438
actual = Variable.concat(
@@ -451,16 +451,12 @@ def test_concat(self):
451451
Variable.concat([v[:, 0], v[:, 1:]], "x")
452452

453453
def test_concat_attrs(self):
454-
# different or conflicting attributes should be removed
454+
# always keep attrs from first variable
455455
v = self.cls("a", np.arange(5), {"foo": "bar"})
456456
w = self.cls("a", np.ones(5))
457457
expected = self.cls(
458458
"a", np.concatenate([np.arange(5), np.ones(5)])
459459
).to_base_variable()
460-
assert_identical(expected, Variable.concat([v, w], "a"))
461-
w.attrs["foo"] = 2
462-
assert_identical(expected, Variable.concat([v, w], "a"))
463-
w.attrs["foo"] = "bar"
464460
expected.attrs["foo"] = "bar"
465461
assert_identical(expected, Variable.concat([v, w], "a"))
466462

0 commit comments

Comments
 (0)