You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
clean up the API for renaming and changing dimensions / coordinates #4825
I wonder if it would be better to first "reorganize" all of the existing functions: we currently have rename (and Dataset.rename_dims / Dataset.rename_vars), set_coords, reset_coords, set_index, reset_index and swap_dims, which overlap partially. For example, the code sample from #4417 works if instead of
ds=ds.rename(b='x')
ds=ds.set_coords('x')
we use
ds=ds.set_index(x="b")
and something similar for the code sample in #4107.
I believe we currently have these use cases (not sure if that list is complete, though):
rename a DataArray → rename
rename a existing variable to a name that is not yet in the object → rename / Dataset.rename_vars / Dataset.rename_dims
convert a data variable to a coordinate (not a dimension coordinate) → set_coords
convert a coordinate (not a dimension coordinate) to a data variable → reset_coords
swap a existing dimension coordinate with a coordinate (which may not exist) and rename the dimension → swap_dims
use a existing coordinate / data variable as a dimension coordinate (do not rename the dimension) → set_index
stop using a coordinate as dimension coordinate and append _ to its name (do not rename the dimension) → reset_index
use two existing coordinates / data variables as a MultiIndex → set_index
stop using a MultiIndex as a dimension coordinate and use its levels as coordinates → reset_index
Sometimes, some of these can be emulated by combinations of others, for example:
# x is a dimension without coordinatesassert_identical(ds.set_index({"x": "b"}), ds.swap_dims({"x": "b"}).rename({"b": "x"}))
assert_identical(ds.swap_dims({"x": "b"}), ds.set_index({"x": "b"}).rename({"x": "b"}))
I agree it's confusing, and I find myself looking up the correct way to do something fairly frequently.
I'm not sure exactly how to rationalize them though.
Without thinking this through in enough detail, Does set_ set the variable to the relevant type and reset_ unsets it to a normal variable?
In that framework, I think the only aberrant is swap_dims, which could instead be set_dims?
There's also rename_dims, but only on a Dataset! There's a TODO to deprecate swap_dims in favor of that. Though I'm not sure that's right — swap_dims changes the dim values for another variable's, but rename_dims just changes the name?
I think that the explicit index refactoring would be an opportunity to clarify things a bit. With no concept of a dimension coordinate/ implicit index, ideally we could have the following behavior with a clear distinction between dimensions/coordinates and indexes, following more closely the "explicit is better than implicit" principle:
set_index / reset_index would only affect the indexes without implicitly renaming any coordinate or dimension.
actually, setting a new index for a given dimension doesn't make much sense anymore with the new data model. Setting a new index for a given set of variables and/or coordinates makes more sense
trying to set an index from non-existing data variables or coordinates would raise a KeyError
.reset_index("x") would not rename the x coordinate to x_
.set_index(x="b") (where x is a dimension without index/coordinate and b is a variable with dimension x) would be replaced by a more explicit set_index("b").rename({"b": "x"}). Renaming b to x wouldn't even be necessary if we want to use the b coordinate as an index.
rename_* would only affect the name of coordinates or dimensions (or the name of the DataArray) without implicitly adding or removing any index.
.set_coords("b").rename({"b": "x"}) in the example above would not implictly create an index for the "x" coordinate
swap_dims would only affect the existing dimension names without implicitly adding or removing any index and without renaming any coordinate.
This would be in an ideal world, though. More practically, I don't know how we could make a smooth transition.
There's also rename_dims, but only on a Dataset! There's a TODO to deprecate swap_dims in favor of that. Though I'm not sure that's right — swap_dims changes the dim values for another variable's, but rename_dims just changes the name?
swap_dims used as a workaround for switching from one to another coordinate as index on a dimension will no longer be needed after the explicit indexes refactoring. Should we eventually depreciate it, then?
Activity
max-sixty commentedon Jan 19, 2021
I agree it's confusing, and I find myself looking up the correct way to do something fairly frequently.
I'm not sure exactly how to rationalize them though.
Without thinking this through in enough detail, Does
set_set the variable to the relevant type andreset_unsets it to a normal variable?In that framework, I think the only aberrant is
swap_dims, which could instead beset_dims?max-sixty commentedon Jan 24, 2021
There's also
rename_dims, but only on a Dataset! There's a TODO to deprecateswap_dimsin favor of that. Though I'm not sure that's right —swap_dimschanges the dim values for another variable's, butrename_dimsjust changes the name?dcherian commentedon Jan 25, 2021
How about
rename_*should only allow renaming to unused names,swap_dimsshould only work with existing names.set_indexshould raise an error for the "renaming" and "swapping" cases.keewis commentedon Jan 25, 2021
if we do 2 I think we should add a
new_dimskwarg toreset_index, otherwise swapping to a dimension without a coordinate is a lot more difficult.benbovy commentedon Sep 10, 2021
I think that the explicit index refactoring would be an opportunity to clarify things a bit. With no concept of a dimension coordinate/ implicit index, ideally we could have the following behavior with a clear distinction between dimensions/coordinates and indexes, following more closely the "explicit is better than implicit" principle:
set_index/reset_indexwould only affect the indexes without implicitly renaming any coordinate or dimension.KeyError.reset_index("x")would not rename thexcoordinate tox_.set_index(x="b")(wherexis a dimension without index/coordinate andbis a variable with dimensionx) would be replaced by a more explicitset_index("b").rename({"b": "x"}). Renamingbtoxwouldn't even be necessary if we want to use thebcoordinate as an index.rename_*would only affect the name of coordinates or dimensions (or the name of the DataArray) without implicitly adding or removing any index..set_coords("b").rename({"b": "x"})in the example above would not implictly create an index for the "x" coordinateswap_dimswould only affect the existing dimension names without implicitly adding or removing any index and without renaming any coordinate.This would be in an ideal world, though. More practically, I don't know how we could make a smooth transition.
swap_dimsused as a workaround for switching from one to another coordinate as index on a dimension will no longer be needed after the explicit indexes refactoring. Should we eventually depreciate it, then?