Skip to content

Commit

Permalink
Closes pydata#4658
Browse files Browse the repository at this point in the history
- Use get_index(dim) in drop_sel
- Add drop_isel
  • Loading branch information
mesejo committed Jan 17, 2021
1 parent a2b1712 commit 1617485
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 3 deletions.
1 change: 1 addition & 0 deletions doc/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ Indexing
Dataset.isel
Dataset.sel
Dataset.drop_sel
Dataset.drop_isel
Dataset.head
Dataset.tail
Dataset.thin
Expand Down
1 change: 1 addition & 0 deletions doc/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ Bug fixes
- Expand user directory paths (e.g. ``~/``) in :py:func:`open_mfdataset` and
:py:meth:`Dataset.to_zarr` (:issue:`4783`, :pull:`4795`).
By `Julien Seguinot <https://github.com/juseg>`_.
- Add :py:meth:`Dataset.drop_isel` (:issue:`4658`, :pull:`4819`). By `Daniel Mesejo <https://github.com/mesejo>`_.

Documentation
~~~~~~~~~~~~~
Expand Down
57 changes: 56 additions & 1 deletion xarray/core/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -4053,13 +4053,68 @@ def drop_sel(self, labels=None, *, errors="raise", **labels_kwargs):
labels_for_dim = [labels_for_dim]
labels_for_dim = np.asarray(labels_for_dim)
try:
index = self.indexes[dim]
index = self.get_index(dim)
except KeyError:
raise ValueError("dimension %r does not have coordinate labels" % dim)
new_index = index.drop(labels_for_dim, errors=errors)
ds = ds.loc[{dim: new_index}]
return ds

def drop_isel(self, indexers=None, **indexers_kwargs):
"""Drop index positions from this dataset.
Parameters
----------
indexers : mapping of hashable to Any
Index locations to drop
**indexers_kwargs : {dim: position, ...}, optional
The keyword arguments form of ``dim`` and ``positions``
Returns
-------
dropped : Dataset
Raises
------
IndexError
Examples
--------
>>> data = np.random.randn(2, 3)
>>> labels = ["a", "b", "c"]
>>> ds = xr.Dataset({"A": (["x", "y"], data), "y": labels})
>>> ds.drop_isel(y=[0, 2])
<xarray.Dataset>
Dimensions: (x: 2, y: 1)
Coordinates:
* y (y) <U1 'b'
Dimensions without coordinates: x
Data variables:
A (x, y) float64 0.4002 1.868
>>> ds.drop_isel(y=1)
<xarray.Dataset>
Dimensions: (x: 2, y: 2)
Coordinates:
* y (y) <U1 'a' 'c'
Dimensions without coordinates: x
Data variables:
A (x, y) float64 1.764 0.9787 2.241 -0.9773
"""

indexers = either_dict_or_kwargs(indexers, indexers_kwargs, "drop")

ds = self
for dim, pos_for_dim in indexers.items():
# Don't cast to set, as it would harm performance when labels
# is a large numpy array
if utils.is_scalar(pos_for_dim):
pos_for_dim = [pos_for_dim]
pos_for_dim = np.asarray(pos_for_dim).tolist()
index = self.get_index(dim)
new_index = index.delete(pos_for_dim)
ds = ds.loc[{dim: new_index}]
return ds

def drop_dims(
self, drop_dims: Union[Hashable, Iterable[Hashable]], *, errors: str = "raise"
) -> "Dataset":
Expand Down
29 changes: 27 additions & 2 deletions xarray/tests/test_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -2371,8 +2371,12 @@ def test_drop_index_labels(self):
data.drop(DataArray(["a", "b", "c"]), dim="x", errors="ignore")
assert_identical(expected, actual)

with raises_regex(ValueError, "does not have coordinate labels"):
data.drop_sel(y=1)
actual = data.drop_sel(y=[1])
expected = data.isel(y=[0, 2])
assert_identical(expected, actual)

with raises_regex(KeyError, "not found in axis"):
data.drop_sel(x=0)

def test_drop_labels_by_keyword(self):
data = Dataset(
Expand Down Expand Up @@ -2410,6 +2414,27 @@ def test_drop_labels_by_keyword(self):
with pytest.raises(ValueError):
data.drop(dim="x", x="a")

def test_drop_labels_by_position(self):
data = Dataset(
{"A": (["x", "y"], np.random.randn(2, 6)), "x": ["a", "b"], "y": range(6)}
)
# Basic functionality.
assert len(data.coords["x"]) == 2

ds2 = data.drop_isel(x=0)
ds3 = data.drop_isel(x=[0])
ds4 = data.drop_isel(x=[0, 1])
ds5 = data.drop_isel(x=[0, 1], y=range(0, 6, 2))

assert_array_equal(ds2.coords["x"], ["b"])
assert_array_equal(ds3.coords["x"], ["b"])
assert ds4.coords["x"].size == 0
assert ds5.coords["x"].size == 0
assert_array_equal(ds5.coords["y"], [1, 3, 5])

with pytest.raises(KeyError):
data.drop_isel(z=1)

def test_drop_dims(self):
data = xr.Dataset(
{
Expand Down

0 comments on commit 1617485

Please sign in to comment.