home / github / issue_comments

Menu
  • Search all tables
  • GraphQL API

issue_comments: 1240646680

This data as json

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
Powered by Datasette · Queries took 0.64ms · About: xarray-datasette