Skip to content

Commit 71177d4

Browse files
benbovyIllviljanpre-commit-ci[bot]
authored
Add Coordinates.assign() method (#8102)
* add Coordinates.assign method * update what's new * test typing Co-authored-by: Illviljan <14371165+Illviljan@users.noreply.github.com> * add docstring examples * fix doctests * fix doctests (spaces) * doctests typo again * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix assign test after merging main --------- Co-authored-by: Illviljan <14371165+Illviljan@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent dd09bdd commit 71177d4

File tree

4 files changed

+71
-2
lines changed

4 files changed

+71
-2
lines changed

doc/api-hidden.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
Coordinates.to_dataset
2323
Coordinates.to_index
2424
Coordinates.update
25+
Coordinates.assign
2526
Coordinates.merge
2627
Coordinates.copy
2728
Coordinates.equals
@@ -39,8 +40,9 @@
3940
core.coordinates.DatasetCoordinates.to_dataset
4041
core.coordinates.DatasetCoordinates.to_index
4142
core.coordinates.DatasetCoordinates.update
43+
core.coordinates.DatasetCoordinates.assign
4244
core.coordinates.DatasetCoordinates.merge
43-
core.coordinates.DataArrayCoordinates.copy
45+
core.coordinates.DatasetCoordinates.copy
4446
core.coordinates.DatasetCoordinates.equals
4547
core.coordinates.DatasetCoordinates.identical
4648

@@ -79,6 +81,7 @@
7981
core.coordinates.DataArrayCoordinates.to_dataset
8082
core.coordinates.DataArrayCoordinates.to_index
8183
core.coordinates.DataArrayCoordinates.update
84+
core.coordinates.DataArrayCoordinates.assign
8285
core.coordinates.DataArrayCoordinates.merge
8386
core.coordinates.DataArrayCoordinates.copy
8487
core.coordinates.DataArrayCoordinates.equals

doc/whats-new.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ v2023.08.1 (unreleased)
2222
New Features
2323
~~~~~~~~~~~~
2424

25+
- Added the :py:meth:`Coordinates.assign` method that can be used to combine
26+
different collections of coordinates prior to assign them to a Dataset or
27+
DataArray (:pull:`8102`) at once.
28+
By `Benoît Bovy <https://github.com/benbovy>`_.
2529

2630
Breaking changes
2731
~~~~~~~~~~~~~~~~

xarray/core/coordinates.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,12 @@
2424
)
2525
from xarray.core.merge import merge_coordinates_without_align, merge_coords
2626
from xarray.core.types import Self, T_DataArray
27-
from xarray.core.utils import Frozen, ReprObject, emit_user_level_warning
27+
from xarray.core.utils import (
28+
Frozen,
29+
ReprObject,
30+
either_dict_or_kwargs,
31+
emit_user_level_warning,
32+
)
2833
from xarray.core.variable import Variable, as_variable, calculate_dimensions
2934

3035
if TYPE_CHECKING:
@@ -560,6 +565,53 @@ def update(self, other: Mapping[Any, Any]) -> None:
560565

561566
self._update_coords(coords, indexes)
562567

568+
def assign(
569+
self, coords: Mapping | None = None, **coords_kwargs: Any
570+
) -> Coordinates:
571+
"""Assign new coordinates (and indexes) to a Coordinates object, returning
572+
a new object with all the original coordinates in addition to the new ones.
573+
574+
Parameters
575+
----------
576+
coords : :class:`Coordinates` or mapping of hashable to Any
577+
Mapping from coordinate names to the new values. If a ``Coordinates``
578+
object is passed, its indexes are assigned in the returned object.
579+
Otherwise, a default (pandas) index is created for each dimension
580+
coordinate found in the mapping.
581+
**coords_kwargs
582+
The keyword arguments form of ``coords``.
583+
One of ``coords`` or ``coords_kwargs`` must be provided.
584+
585+
Returns
586+
-------
587+
new_coords : Coordinates
588+
A new Coordinates object with the new coordinates (and indexes)
589+
in addition to all the existing coordinates.
590+
591+
Examples
592+
--------
593+
>>> coords = xr.Coordinates()
594+
>>> coords
595+
Coordinates:
596+
*empty*
597+
598+
>>> coords.assign(x=[1, 2])
599+
Coordinates:
600+
* x (x) int64 1 2
601+
602+
>>> midx = pd.MultiIndex.from_product([["a", "b"], [0, 1]])
603+
>>> coords.assign(xr.Coordinates.from_pandas_multiindex(midx, "y"))
604+
Coordinates:
605+
* y (y) object MultiIndex
606+
* y_level_0 (y) object 'a' 'a' 'b' 'b'
607+
* y_level_1 (y) int64 0 1 0 1
608+
609+
"""
610+
coords = either_dict_or_kwargs(coords, coords_kwargs, "assign")
611+
new_coords = self.copy()
612+
new_coords.update(coords)
613+
return new_coords
614+
563615
def _overwrite_indexes(
564616
self,
565617
indexes: Mapping[Any, Index],

xarray/tests/test_coordinates.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,16 @@ def test_identical(self):
124124
assert coords.identical(coords)
125125
assert not coords.identical("not_a_coords")
126126

127+
def test_assign(self) -> None:
128+
coords = Coordinates(coords={"x": [0, 1, 2]})
129+
expected = Coordinates(coords={"x": [0, 1, 2], "y": [3, 4]})
130+
131+
actual = coords.assign(y=[3, 4])
132+
assert_identical(actual, expected)
133+
134+
actual = coords.assign({"y": [3, 4]})
135+
assert_identical(actual, expected)
136+
127137
def test_copy(self) -> None:
128138
no_index_coords = Coordinates({"foo": ("x", [1, 2, 3])})
129139
copied = no_index_coords.copy()

0 commit comments

Comments
 (0)