[API]: inconsistent `rename` for DataArray vs Dataset
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 4.2k
- Forks
- 1.4k
- Avg merge
- 2d 15h
- Merged PRs (30d)
- 14
Description
What happened?
The DataArray.rename API is inconsistent with Dataset.rename and the documentation does not make that obvious.
Unlike Dataset.rename,
- A DataArray cannot be renamed using a keyword argument, but fails saying "[name] is not a variable or dimension in this dataset" (example A below).
- Passing the new name as a positional argument, but with other keyword arguments fails with the statement "the first argument to .rename must be a dictionary" (example B below).
- As a consequence, renaming the array as well as its dimension(s)/coordinate(s) requires two separate function calls, i.e.
da.rename("newname").rename("dim_0"="x").
Examples
Start with an array, da, and a dataset, ds
>>> da = xr.DataArray(
np.zeros((2,3)),
name="alpha",
coords={"x":range(2), "y":range(3)}
)
>>> da
<xarray.DataArray 'alpha' (x: 2, y: 3)>
array([[0., 0., 0.],
[0., 0., 0.]])
Coordinates:
* x (x) int64 0 1
* y (y) int64 0 1 2
>>> ds = xr.Dataset({"alpha":da})
>>> ds
<xarray.Dataset>
Dimensions: (x: 2, y: 3)
Coordinates:
* x (x) int64 0 1
* y (y) int64 0 1 2
Data variables:
alpha (x, y) float64 0.0 0.0 0.0 0.0 0.0 0.0
Dataset example
ds.rename renames everything at once using keyword arguments
>>> ds.rename(x="i", y="j", alpha="beta")
<xarray.Dataset>
Dimensions: (i: 2, j: 3)
Coordinates:
* i (i) int64 0 1
* j (j) int64 0 1 2
Data variables:
beta (i, j) float64 0.0 0.0 0.0 0.0 0.0 0.0
Example A
da.rename does not recognize the array's current name as a keyword and returns a confusing error message.
>>> da.rename(alpha="beta")
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-98-af366146dc6f> in <module>
----> 1 da.rename(alpha="beta", x="i")
xarray/core/dataarray.py in rename(self, new_name_or_name_dict, **names)
1842 )
1843 name_dict = either_dict_or_kwargs(new_name_or_name_dict, names, "rename")
-> 1844 dataset = self._to_temp_dataset().rename(name_dict)
1845 return self._from_temp_dataset(dataset)
1846 else:
xarray/core/dataset.py in rename(self, name_dict, **names)
3390 for k in name_dict.keys():
3391 if k not in self and k not in self.dims:
-> 3392 raise ValueError(
3393 f"cannot rename {k!r} because it is not a "
3394 "variable or dimension in this dataset"
ValueError: cannot rename 'alpha' because it is not a variable or dimension in this dataset
Example B
da.rename will not change the name of the array as well as the dimension(s)/coordinate(s) names and emits an untrue error message, since the array cannot be renamed using a dict.
>>> da.rename("beta", x="i")
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-99-f90b078d6bd5> in <module>
----> 1 da.rename("beta", x="i")
xarray/core/dataarray.py in rename(self, new_name_or_name_dict, **names)
1841 Mapping[Hashable, Hashable], new_name_or_name_dict
1842 )
-> 1843 name_dict = either_dict_or_kwargs(new_name_or_name_dict, names, "rename")
1844 dataset = self._to_temp_dataset().rename(name_dict)
1845 return self._from_temp_dataset(dataset)
xarray/core/utils.py in either_dict_or_kwargs(pos_kwargs, kw_kwargs, func_name)
284
285 if not is_dict_like(pos_kwargs):
--> 286 raise ValueError(f"the first argument to .{func_name} must be a dictionary")
287 if kw_kwargs:
288 raise ValueError(
ValueError: the first argument to .rename must be a dictionary
What did you expect to happen?
No response
Minimal Complete Verifiable Example
No response
Relevant log output
No response
Anything else we need to know?
No response
Environment
INSTALLED VERSIONS
commit: None
python: 3.9.10 | packaged by conda-forge | (main, Feb 1 2022, 21:25:34)
[Clang 11.1.0 ]
python-bits: 64
OS: Darwin
OS-release: 21.1.0
machine: arm64
processor: arm
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8
LOCALE: ('en_US', 'UTF-8')
libhdf5: 1.12.1
libnetcdf: 4.8.1
xarray: 0.21.1
pandas: 1.3.5
numpy: 1.22.2
scipy: 1.7.1
netCDF4: 1.5.7
pydap: None
h5netcdf: None
h5py: None
Nio: None
zarr: None
cftime: 1.5.2
nc_time_axis: None
PseudoNetCDF: None
rasterio: None
cfgrib: None
iris: None
bottleneck: 1.3.2
dask: None
distributed: None
matplotlib: 3.5.0
cartopy: None
seaborn: None
numbagg: None
fsspec: None
cupy: None
pint: None
sparse: None
setuptools: 60.7.1
pip: 22.0.3
conda: None
pytest: None
IPython: 7.29.0
sphinx: None
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the rename implementations shown in xarray/core/dataarray.py and xarray/core/dataset.py, and reproduce Examples A and B in a local checkout. Clarify the intended DataArray API for combining array-name and dimension or coordinate renames; done means consistent behavior with Dataset.rename and coverage for both examples.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- data
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 40/100