html_url,issue_url,id,node_id,user,created_at,updated_at,author_association,body,reactions,performed_via_github_app,issue
https://github.com/pydata/xarray/issues/7005#issuecomment-1240646680,https://api.github.com/repos/pydata/xarray/issues/7005,1240646680,IC_kwDOAMm_X85J8sQY,1797906,2022-09-08T12:24:41Z,2022-09-08T12:24:41Z,NONE,"Hi @benbovy,
Thanks for the detailed response.
Yeah, that it was only raising for the second multi indexing map, does seem like a bug in that case, I'll leave the ticket open to track that.
I didn't stumble on the `set_levels` function while skimming though the docs, thanks. I've updated my function to make use of that. I'm hoping things should be safe with this, and I'm correctly replacing things in the correct order.
For anyone else who's looking to do the same, or for anyone to tell me what I'm doing is not safe, or there's a simpler way, here's the updated function:
```python
import numpy as np
import pandas as pd
import xarray as xr
def map_coords(ds, *, name, mapping):
""""""
Takes a xarray dataset's coordinate values and updates
them with the given the provided mapping. In-place.
Can handle both regular indices and multi-level indices.
ds: An xr.Datset
name: name of the coordinate to update
mapping: dictionary, key of old value, value of new value.
""""""
# all attrs seem to get dropped on coords even if only
# one is altered. Hold on to them and reapply after
coord_attrs = {c: ds[c].attrs for c in ds.coords}
if ds.indexes.is_multi(name):
target = name
parent = ds.indexes[target].name
if target == parent:
valid_targets = ds.indexes[parent].names
raise ValueError(
f""Can only map levels of a MultiIndex, not the MultiIndex ""
f""itself. Target one of {valid_targets}"",
)
multi_index = ds.indexes[parent]
level_values = dict(zip(multi_index.names, multi_index.levels))
new_values = [mapping[v] for v in level_values[name]]
ds.coords[parent] = multi_index.set_levels(new_values, level=target)
else:
old_values = ds.coords[name].values
new_values = [mapping[v] for v in old_values]
ds[name] = new_values
# reapply attrs
for coord, attrs in coord_attrs.items():
ds[coord].attrs = attrs
midx = pd.MultiIndex.from_product([list(""abc""), [0, 1]], names=(""x_one"", ""x_two""))
midy = pd.MultiIndex.from_product([list(""abc""), [0, 1]], names=(""y_one"", ""y_two""))
mda = xr.DataArray(np.random.rand(6, 6, 3), [(""x"", midx), (""y"", midy), (""z"", range(3))])
map_coords(mda, name=""z"", mapping={0: ""zero"", 1: ""one"", 2: ""two""})
map_coords(mda, name=""x_one"", mapping={""a"": ""aa"", ""b"": ""bb"", ""c"": ""cc""})
map_coords(mda, name=""y_one"", mapping={""a"": ""aa"", ""b"": ""bb"", ""c"": ""cc""})
print(mda)
```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,1364911775