Description
What happened?
When I generate a stacked multiindex coordinate dataset
ds = xr.Dataset(
data_vars={"d": (["x", "y"], np.random.randn(2, 3))},
coords={"x": [3, 4], "y": [0.5, 1.2, 2.0]},
)
ds2 = ds.stack({"z": ["x", "y"]})
indexing the unstacked version of the data ds
with both an integer as well as a float value
ds.sel(x=3)
ds.sel(y=1.2)
works without a problem. But if I try to index the stacked version ds2
ds2.sel(x=3)
ds2.sel(y=1.2)
the integer indexing works, but the float indexing ds2.sel(y=1.2)
fails with an InvalidIndexError
.
The pandas
version works without any problem:
df = ds2["d"].to_pandas()
df[:, 1.2]
The problems seems to lie in xarray.core.utils.py
in the maybe_cast_to_coords_dtype
function
def maybe_cast_to_coords_dtype(label, coords_dtype):
if coords_dtype.kind == "f" and not isinstance(label, slice):
label = np.asarray(label, dtype=coords_dtype)
return label
that explicitly calls np.asarray
on the coordinate label. This then later fails in pandas.core.indexes
via the _check_indexing_error
method, where it is checked that the label is a scalar, which it was before maybe_cast_to_coords_dtype
converted it. Why does this conversion happen there at all?
What did you expect to happen?
Expecting ds2.sel(x=3)
to return:
<xarray.Dataset>
Dimensions: (x: 2)
Coordinates:
* x (x) int64 3 4
Data variables:
d (x) int64 1 4
Minimal Complete Verifiable Example
import xarray as xr
ds = xr.Dataset(
data_vars={"d": (["x", "y"], [[0, 1, 2], [3, 4, 5]])},
coords={"x": [3, 4], "y": [0.5, 1.2, 2.0]},
)
ds2 = ds.stack({"z": ["x", "y"]})
ds2.sel(y=1.2)
MVCE confirmation
- Minimal example — the example is as focused as reasonably possible to demonstrate the underlying issue in xarray.
- Complete example — the example is self-contained, including all data and the text of any traceback.
- Verifiable example — the example copy & pastes into an IPython prompt or Binder notebook, returning the result.
- New issue — a search of GitHub Issues suggests this is not a duplicate.
Relevant log output
Traceback (most recent call last):
File "~/.miniconda3/envs/artiq/lib/python3.8/site-packages/pandas/core/indexes/base.py", line 3621, in get_loc
return self._engine.get_loc(casted_key)
File "pandas/_libs/index.pyx", line 136, in pandas._libs.index.IndexEngine.get_loc
File "pandas/_libs/index.pyx", line 142, in pandas._libs.index.IndexEngine.get_loc
TypeError: '1.2' is an invalid key
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "~/.miniconda3/envs/artiq/lib/python3.8/site-packages/spyder_kernels/py3compat.py", line 356, in compat_exec
exec(code, globals, locals)
File "~/data_import.py", line 65, in <module>
xr.Dataset(
File "~/.miniconda3/envs/artiq/lib/python3.8/site-packages/xarray/core/dataset.py", line 2501, in sel
pos_indexers, new_indexes = remap_label_indexers(
File "~/.miniconda3/envs/artiq/lib/python3.8/site-packages/xarray/core/coordinates.py", line 421, in remap_label_indexers
pos_indexers, new_indexes = indexing.remap_label_indexers(
File "~/.miniconda3/envs/artiq/lib/python3.8/site-packages/xarray/core/indexing.py", line 121, in remap_label_indexers
idxr, new_idx = index.query(labels, method=method, tolerance=tolerance)
File "~/.miniconda3/envs/artiq/lib/python3.8/site-packages/xarray/core/indexes.py", line 353, in query
indexer, new_index = self.index.get_loc_level(
File "~/.miniconda3/envs/artiq/lib/python3.8/site-packages/pandas/core/indexes/multi.py", line 2972, in get_loc_level
loc, mi = self._get_loc_level(key, level=level)
File "~/.miniconda3/envs/artiq/lib/python3.8/site-packages/pandas/core/indexes/multi.py", line 3005, in _get_loc_level
loc, new_index = self._get_loc_level(k, level=lev)
File "~/.miniconda3/envs/artiq/lib/python3.8/site-packages/pandas/core/indexes/multi.py", line 3113, in _get_loc_level
indexer = self._get_level_indexer(key, level=level)
File "~/.miniconda3/envs/artiq/lib/python3.8/site-packages/pandas/core/indexes/multi.py", line 3222, in _get_level_indexer
idx = self._get_loc_single_level_index(level_index, key)
File "~/.miniconda3/envs/artiq/lib/python3.8/site-packages/pandas/core/indexes/multi.py", line 2802, in _get_loc_single_level_index
return level_index.get_loc(key)
File "~/.miniconda3/envs/artiq/lib/python3.8/site-packages/pandas/core/indexes/base.py", line 3628, in get_loc
self._check_indexing_error(key)
File "~/.miniconda3/envs/artiq/lib/python3.8/site-packages/pandas/core/indexes/base.py", line 5637, in _check_indexing_error
raise InvalidIndexError(key)
InvalidIndexError: 1.2
Anything else we need to know?
No response
Environment
INSTALLED VERSIONS
commit: None
python: 3.8.13 | packaged by conda-forge | (default, Mar 25 2022, 06:04:10)
[GCC 10.3.0]
python-bits: 64
OS: Linux
OS-release: 5.17.5-76051705-generic
machine: x86_64
processor: x86_64
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8
LOCALE: ('en_US', 'UTF-8')
libhdf5: 1.12.1
libnetcdf: 4.8.1
xarray: 2022.3.0
pandas: 1.4.3
numpy: 1.23.1
scipy: 1.8.1
netCDF4: 1.6.0
pydap: None
h5netcdf: 1.0.1
h5py: 3.7.0
Nio: None
zarr: 2.12.0
cftime: 1.6.1
nc_time_axis: None
PseudoNetCDF: None
rasterio: None
cfgrib: None
iris: None
bottleneck: None
dask: None
distributed: None
matplotlib: 3.5.2
cartopy: None
seaborn: None
numbagg: None
fsspec: None
cupy: None
pint: None
sparse: None
setuptools: 63.2.0
pip: 22.1.2
conda: None
pytest: None
IPython: 7.33.0
sphinx: 5.0.2
/home/thorsten/.miniconda3/envs/artiq/lib/python3.8/site-packages/_distutils_hack/init.py:33: UserWarning: Setuptools is replacing distutils.
warnings.warn("Setuptools is replacing distutils.")