Skip to content

Commit a2df249

Browse files
committed
Infer coord for array concat
This is really nice to have when using concat to produce faceted plots of various kinds, and harmless when it's useless.
1 parent 01ba1f8 commit a2df249

File tree

3 files changed

+17
-2
lines changed

3 files changed

+17
-2
lines changed

doc/whats-new.rst

+3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ Enhancements
4040
`Spencer Clark <https://github.com/spencerkclark>`_.
4141
- Add ``data=False`` option to ``to_dict()`` methods. (:issue:`2656`)
4242
By `Ryan Abernathey <https://github.com/rabernat>`_
43+
- Use new dimension name and unique array names to create a new coordinate
44+
when concatenating arrays, if no coordinates are given.
45+
(:issue:`2775`). By `Zac Hatfield-Dodds <https://github.com/Zac-HD>`_.
4346
- :py:meth:`~xarray.DataArray.coarsen` and
4447
:py:meth:`~xarray.Dataset.coarsen` are newly added.
4548
See :ref:`comput.coarsen` for details.

xarray/core/combine.py

+7
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,13 @@ def _dataarray_concat(arrays, dim, data_vars, coords, compat,
329329
raise ValueError('array names not identical')
330330
datasets = [arr.rename(name)._to_temp_dataset() for arr in arrays]
331331

332+
if name is None and isinstance(dim, str) and dim not in arrays[0].dims:
333+
# If we're concatenating uniquely named arrays along a new dimension,
334+
# use the existing names as coordinates.
335+
names = [arr.name for arr in arrays]
336+
if len(set(names) - {None}) == len(names):
337+
dim = pd.Index(names, name=dim)
338+
332339
ds = _dataset_concat(datasets, dim, data_vars, coords, compat,
333340
positions)
334341
return arrays[0]._from_temp_dataset(ds, name)

xarray/tests/test_combine.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,8 @@ def test_concat(self):
248248

249249
# from dataset array:
250250
expected = DataArray(np.array([foo.values, bar.values]),
251-
dims=['w', 'x', 'y'], coords={'x': [0, 1]})
251+
dims=['w', 'x', 'y'],
252+
coords={'x': [0, 1], 'w': ['foo', 'bar']})
252253
actual = concat([foo, bar], 'w')
253254
assert_equal(expected, actual)
254255
# from iteration:
@@ -297,15 +298,19 @@ def test_concat_lazy(self):
297298
assert combined.shape == (2, 3, 3)
298299
assert combined.dims == ('z', 'x', 'y')
299300

300-
def test_concat_names(self):
301+
def test_concat_names_and_coords(self):
301302
ds = Dataset({'foo': (['x', 'y'], np.random.random((2, 2))),
302303
'bar': (['x', 'y'], np.random.random((2, 2)))})
303304
# Concat arrays with different names, new name is None
305+
# and unique array names are used as coordinates
304306
new = concat([ds.foo, ds.bar], dim='new')
305307
assert new.name is None
308+
assert (new.coords['new'] == ['foo', 'bar']).values.all()
306309
# Concat arrays with same name, name is preserved
310+
# and non-unique names are not used as coords
307311
foobar = ds.foo.rename('bar')
308312
assert concat([foobar, ds.bar], dim='new').name == 'bar'
313+
assert 'new' not in concat([foobar, ds.bar], dim='new').coords
309314

310315

311316
class TestAutoCombine(object):

0 commit comments

Comments
 (0)