xarray: Dataset.drop() no longer works with a set as an argument

MCVE Code Sample

# Your code here
#!/usr/bin/env python

import xarray
import numpy

ds = xarray.Dataset()
ds['x'] = ('x', numpy.linspace(0., 1., 100))
ds['y'] = ('y', numpy.linspace(0., 1., 50))
print(ds)
ds = ds.drop(set('x'))
print(ds)

Expected Output

<xarray.Dataset>
Dimensions:  (x: 100, y: 50)
Coordinates:
  * x        (x) float64 0.0 0.0101 0.0202 0.0303 ... 0.9697 0.9798 0.9899 1.0
  * y        (y) float64 0.0 0.02041 0.04082 0.06122 ... 0.9592 0.9796 1.0
Data variables:
    *empty*
<xarray.Dataset>
Dimensions:  (y: 50)
Coordinates:
  * y        (y) float64 0.0 0.02041 0.04082 0.06122 ... 0.9592 0.9796 1.0
Data variables:
    *empty*

Problem Description

In versions before xarray 0.14.1, the code above involving calls to Dataset.drop() with a set as an argument worked as expected. With the new release, the result is an error as shown below. This is breaking backwards compatibility with our software (MPAS-Analysis).

<xarray.Dataset>
Dimensions:  (x: 100, y: 50)
Coordinates:
  * x        (x) float64 0.0 0.0101 0.0202 0.0303 ... 0.9697 0.9798 0.9899 1.0
  * y        (y) float64 0.0 0.02041 0.04082 0.06122 ... 0.9592 0.9796 1.0
Data variables:
    *empty*
Traceback (most recent call last):
  File "./drop_issue.py", line 10, in <module>
    ds = ds.drop(set('x'))
  File "/home/xylar/miniconda3/envs/test/lib/python3.7/site-packages/xarray/core/dataset.py", line 3643, in drop
    return self.drop_sel(labels, errors=errors)
  File "/home/xylar/miniconda3/envs/test/lib/python3.7/site-packages/xarray/core/dataset.py", line 3689, in drop_sel
    labels = either_dict_or_kwargs(labels, labels_kwargs, "drop")
  File "/home/xylar/miniconda3/envs/test/lib/python3.7/site-packages/xarray/core/utils.py", line 257, in either_dict_or_kwargs
    "the first argument to .%s must be a dictionary" % func_name
ValueError: the first argument to .drop must be a dictionary

Output of xr.show_versions()

# Paste the output here xr.show_versions() here INSTALLED VERSIONS ------------------ commit: None python: 3.7.3 | packaged by conda-forge | (default, Jul 1 2019, 21:52:21) [GCC 7.3.0] python-bits: 64 OS: Linux OS-release: 4.15.0-1063-oem machine: x86_64 processor: x86_64 byteorder: little LC_ALL: None LANG: en_US.UTF-8 LOCALE: en_US.UTF-8 libhdf5: 1.10.5 libnetcdf: 4.7.1

xarray: 0.14.1 pandas: 0.25.3 numpy: 1.17.3 scipy: 1.3.2 netCDF4: 1.5.3 pydap: None h5netcdf: None h5py: None Nio: None zarr: None cftime: 1.0.4.2 nc_time_axis: None PseudoNetCDF: None rasterio: None cfgrib: None iris: None bottleneck: 1.3.1 dask: 2.8.0 distributed: 2.8.0 matplotlib: 3.1.2 cartopy: 0.17.0 seaborn: None numbagg: None setuptools: 41.6.0.post20191101 pip: 19.3.1 conda: None pytest: 5.3.0 IPython: None sphinx: None

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 15 (5 by maintainers)

Commits related to this issue

Most upvoted comments

the reason for set raising an error is that in drop is_list_like(labels) or is_scalar(labels) is used instead of isinstance(labels, str) or not isinstance(labels, Iterable). Since is_list_like explicitly checks for tuple and list, passing set obviously won’t call the right method.

Ah, thanks very much! I’ll switch to using that syntax instead.

explicitly selecting should work like this:

ds = xr.Dataset(
    {"a": ("b", [0, 1, 2]), "c": ("b", [-1, 2, 4]), "d": ("b", [5, 1, 3])},
    coords={"b": list("abc")},
)
variables = ["a", "d"]
ds[variables]

I think Dataset.__getitem__ allows any kind of sequence here (e.g. sets)

so I guess we need to figure out why sets don’t work anymore?