Skip to content

Support alignment with partial overlap between index vs. excluded dimensions #10243

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
benbovy opened this issue Apr 23, 2025 · 2 comments · May be fixed by #10293
Open

Support alignment with partial overlap between index vs. excluded dimensions #10243

benbovy opened this issue Apr 23, 2025 · 2 comments · May be fixed by #10293

Comments

@benbovy
Copy link
Member

benbovy commented Apr 23, 2025

Is your feature request related to a problem?

In dcherian/rasterix#20 we hit a case where it is useful to concatenate objects over a dimension that is "tied" with other, non-concatenated dimension(s) by an index.

For example let's say that we want to concatenate over the x dimension multiple raster dataarrays that each associate their x / y spatial dimension coordinates together with a RasterIndex. This means exclude only dimension x from the alignment of those dataarrays.

This is currently not supported by Xarray. An error is explicitly raised here:

elif exclude_dims:
excl_dims_str = ", ".join(str(d) for d in exclude_dims)
incl_dims_str = ", ".join(str(d) for d in all_dims - exclude_dims)
raise ValueError(
f"cannot exclude dimension(s) {excl_dims_str} from alignment because "
"these are used by an index together with non-excluded dimensions "
f"{incl_dims_str}"
)

Describe the solution you'd like

One general solution, at least for join="exact", would be to allow an Xarray index ignoring one or more dimensions while checking equality with another index: Index.equals(other, exclude_dims: tuple[str, ...]).

This would for example make this possible:

raster_index1.equals(raster_index2, exclude_dims=("x",))
# Returns True -> raster datarrays are aligned on the "y" dimension

RasterIndex.concat([raster_index1, raster_index2], "x")
# Returns a new RasterIndex that combines indexes 1 and 2 over the "x" dimension
# (no need to check their compatibility over the "y" dimension, it has been done already)

We'd also need to ensure that the aligned objects each keep (a copy of) their original index, since they are still different on the dimension(s) excluded from alignment. The current behavior of align(objs, copy=True, join="exact") seems to copy the index of the 1st object and assign it to all new aligned objects, which is not desirable here but which could be easily fixed I think.

Supporting the other join options (left, right, inner, outer, override) does not make much sense since those all consists of assigning a unique index that is common to every new aligned object.

Describe alternatives you've considered

Another suggestion is to auto-exclude from alignment the other dimensions that are linked to the index (i.e., exclude both x and y spatial dimensions in the example above). This is a more drastic solution that doesn't require any change to the Xarray Index API and that does not depend on the option given for join. However it has several downsides:

  • it is implicit and might have surprising behavior
  • we may still want to check strict alignment on the dimensions that have not been excluded explicitly (i.e., the y dimension in the example above), especially if other indexes linked to those dimensions are found in the objects to align.

Additional context

No response

@benbovy
Copy link
Member Author

benbovy commented Apr 24, 2025

Another example is xr.concat([obj1, obj2], dim="x") where both objects have x(x) and x_bounds(bnd, x) coordinates together associated with an IntervalIndex (#8005). Automatically excluding dimension bnd from alignment is pretty safe here, or ignoring it when passed to IntervalIndex.equals() would work just as well.

@benbovy benbovy added topic-indexing topic-combine combine/concat/merge labels Apr 25, 2025
@dcherian
Copy link
Contributor

One general solution, at least for join="exact", would be to allow an Xarray index ignoring one or more dimensions while checking equality with another index: Index.equals(other, exclude_dims: tuple[str, ...]).

These seems OK to me. At least I can't think of a counter example at the moment. An Index can always choose to opt out of this by raising if exclude_dims is not empty, and/or error-ing in Index.concat

@benbovy benbovy linked a pull request May 7, 2025 that will close this issue
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants