Skip to content

Commit 52a16a6

Browse files
gwgundersenmax-sixty
authored andcommitted
Support for dict-like arguments for assign_coords (pydata#3243)
* Issue 3231: Support for dict-like arguments for assign_coords * Amended docstring to clarify two examples. * Simplified documentation by not repeating arguments. Formatting.
1 parent 131f602 commit 52a16a6

File tree

5 files changed

+62
-13
lines changed

5 files changed

+62
-13
lines changed

doc/whats-new.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ Enhancements
7676

7777
Bug fixes
7878
~~~~~~~~~
79+
80+
- :py:meth:`~xarray.DataArray.assign_coords` now supports dictionary arguments
81+
(:issue:`3231`).
82+
By `Gregory Gundersen <https://github.com/gwgundersen>`_.
7983
- Fix regression introduced in v0.12.2 where ``copy(deep=True)`` would convert
8084
unicode indices to dtype=object (:issue:`3094`).
8185
By `Guido Imperiale <https://github.com/crusaderky>`_.

xarray/core/common.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -341,19 +341,23 @@ def _calc_assign_results(
341341
results[k] = v
342342
return results
343343

344-
def assign_coords(self, **kwargs):
344+
def assign_coords(self, coords=None, **coords_kwargs):
345345
"""Assign new coordinates to this object.
346346
347347
Returns a new object with all the original data in addition to the new
348348
coordinates.
349349
350350
Parameters
351351
----------
352-
kwargs : keyword, value pairs
353-
keywords are the variables names. If the values are callable, they
354-
are computed on this object and assigned to new coordinate
355-
variables. If the values are not callable, (e.g. a DataArray,
356-
scalar, or array), they are simply assigned.
352+
coords : dict, optional
353+
A dict with keys which are variables names. If the values are
354+
callable, they are computed on this object and assigned to new
355+
coordinate variables. If the values are not callable,
356+
(e.g. a ``DataArray``, scalar, or array), they are simply assigned.
357+
358+
**coords_kwargs : keyword, value pairs, optional
359+
The keyword arguments form of ``coords``.
360+
One of ``coords`` or ``coords_kwargs`` must be provided.
357361
358362
Returns
359363
-------
@@ -363,7 +367,6 @@ def assign_coords(self, **kwargs):
363367
364368
Examples
365369
--------
366-
367370
Convert longitude coordinates from 0-359 to -180-179:
368371
369372
>>> da = xr.DataArray(np.random.rand(4),
@@ -380,10 +383,18 @@ def assign_coords(self, **kwargs):
380383
Coordinates:
381384
* lon (lon) int64 -2 -1 0 1
382385
386+
The function also accepts dictionary arguments:
387+
388+
>>> da.assign_coords({'lon': (((da.lon + 180) % 360) - 180)})
389+
<xarray.DataArray (lon: 4)>
390+
array([0.28298 , 0.667347, 0.657938, 0.177683])
391+
Coordinates:
392+
* lon (lon) int64 -2 -1 0 1
393+
383394
Notes
384395
-----
385-
Since ``kwargs`` is a dictionary, the order of your arguments may not
386-
be preserved, and so the order of the new variables is not well
396+
Since ``coords_kwargs`` is a dictionary, the order of your arguments may
397+
not be preserved, and so the order of the new variables is not well
387398
defined. Assigning multiple variables within the same ``assign_coords``
388399
is possible, but you cannot reference other variables created within
389400
the same ``assign_coords`` call.
@@ -393,8 +404,9 @@ def assign_coords(self, **kwargs):
393404
Dataset.assign
394405
Dataset.swap_dims
395406
"""
407+
coords_kwargs = either_dict_or_kwargs(coords, coords_kwargs, "assign_coords")
396408
data = self.copy(deep=False)
397-
results = self._calc_assign_results(kwargs)
409+
results = self._calc_assign_results(coords_kwargs)
398410
data.coords.update(results)
399411
return data
400412

xarray/core/groupby.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,13 @@
1111
from .common import ALL_DIMS, ImplementsArrayReduce, ImplementsDatasetReduce
1212
from .options import _get_keep_attrs
1313
from .pycompat import integer_types
14-
from .utils import hashable, maybe_wrap_array, peek_at, safe_cast_to_index
14+
from .utils import (
15+
hashable,
16+
maybe_wrap_array,
17+
peek_at,
18+
safe_cast_to_index,
19+
either_dict_or_kwargs,
20+
)
1521
from .variable import IndexVariable, Variable, as_variable
1622

1723

@@ -507,15 +513,16 @@ def last(self, skipna=None, keep_attrs=None):
507513
"""
508514
return self._first_or_last(duck_array_ops.last, skipna, keep_attrs)
509515

510-
def assign_coords(self, **kwargs):
516+
def assign_coords(self, coords=None, **coords_kwargs):
511517
"""Assign coordinates by group.
512518
513519
See also
514520
--------
515521
Dataset.assign_coords
516522
Dataset.swap_dims
517523
"""
518-
return self.apply(lambda ds: ds.assign_coords(**kwargs))
524+
coords_kwargs = either_dict_or_kwargs(coords, coords_kwargs, "assign_coords")
525+
return self.apply(lambda ds: ds.assign_coords(**coords_kwargs))
519526

520527

521528
def _maybe_reorder(xarray_obj, dim, positions):

xarray/tests/test_dataset.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3198,6 +3198,19 @@ def test_assign(self):
31983198
expected = expected.set_coords("c")
31993199
assert_identical(actual, expected)
32003200

3201+
def test_assign_coords(self):
3202+
ds = Dataset()
3203+
3204+
actual = ds.assign(x=[0, 1, 2], y=2)
3205+
actual = actual.assign_coords(x=list("abc"))
3206+
expected = Dataset({"x": list("abc"), "y": 2})
3207+
assert_identical(actual, expected)
3208+
3209+
actual = ds.assign(x=[0, 1, 2], y=[2, 3])
3210+
actual = actual.assign_coords({"y": [2.0, 3.0]})
3211+
expected = ds.assign(x=[0, 1, 2], y=[2.0, 3.0])
3212+
assert_identical(actual, expected)
3213+
32013214
def test_assign_attrs(self):
32023215
expected = Dataset(attrs=dict(a=1, b=2))
32033216
new = Dataset()

xarray/tests/test_groupby.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,4 +189,17 @@ def test_da_groupby_quantile():
189189
assert_identical(expected, actual)
190190

191191

192+
def test_da_groupby_assign_coords():
193+
actual = xr.DataArray(
194+
[[3, 4, 5], [6, 7, 8]], dims=["y", "x"], coords={"y": range(2), "x": range(3)}
195+
)
196+
actual1 = actual.groupby("x").assign_coords({"y": [-1, -2]})
197+
actual2 = actual.groupby("x").assign_coords(y=[-1, -2])
198+
expected = xr.DataArray(
199+
[[3, 4, 5], [6, 7, 8]], dims=["y", "x"], coords={"y": [-1, -2], "x": range(3)}
200+
)
201+
assert_identical(expected, actual1)
202+
assert_identical(expected, actual2)
203+
204+
192205
# TODO: move other groupby tests from test_dataset and test_dataarray over here

0 commit comments

Comments
 (0)