Skip to content

Commit

Permalink
Remove xarray.ufuncs (#6491)
Browse files Browse the repository at this point in the history
* Remove xarray.ufuncs

* Remove ufunc docs
  • Loading branch information
max-sixty authored Apr 19, 2022
1 parent ea99445 commit 33cdabd
Show file tree
Hide file tree
Showing 8 changed files with 11 additions and 406 deletions.
60 changes: 0 additions & 60 deletions doc/api-hidden.rst
Original file line number Diff line number Diff line change
Expand Up @@ -319,66 +319,6 @@
IndexVariable.sizes
IndexVariable.values

ufuncs.angle
ufuncs.arccos
ufuncs.arccosh
ufuncs.arcsin
ufuncs.arcsinh
ufuncs.arctan
ufuncs.arctan2
ufuncs.arctanh
ufuncs.ceil
ufuncs.conj
ufuncs.copysign
ufuncs.cos
ufuncs.cosh
ufuncs.deg2rad
ufuncs.degrees
ufuncs.exp
ufuncs.expm1
ufuncs.fabs
ufuncs.fix
ufuncs.floor
ufuncs.fmax
ufuncs.fmin
ufuncs.fmod
ufuncs.fmod
ufuncs.frexp
ufuncs.hypot
ufuncs.imag
ufuncs.iscomplex
ufuncs.isfinite
ufuncs.isinf
ufuncs.isnan
ufuncs.isreal
ufuncs.ldexp
ufuncs.log
ufuncs.log10
ufuncs.log1p
ufuncs.log2
ufuncs.logaddexp
ufuncs.logaddexp2
ufuncs.logical_and
ufuncs.logical_not
ufuncs.logical_or
ufuncs.logical_xor
ufuncs.maximum
ufuncs.minimum
ufuncs.nextafter
ufuncs.rad2deg
ufuncs.radians
ufuncs.real
ufuncs.rint
ufuncs.sign
ufuncs.signbit
ufuncs.sin
ufuncs.sinh
ufuncs.sqrt
ufuncs.square
ufuncs.tan
ufuncs.tanh
ufuncs.trunc

plot.plot
plot.line
plot.step
Expand Down
78 changes: 0 additions & 78 deletions doc/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -610,84 +610,6 @@ Plotting
DataArray.plot.step
DataArray.plot.surface

.. _api.ufuncs:

Universal functions
===================

.. warning::

With recent versions of NumPy, Dask and xarray, NumPy ufuncs are now
supported directly on all xarray and Dask objects. This obviates the need
for the ``xarray.ufuncs`` module, which should not be used for new code
unless compatibility with versions of NumPy prior to v1.13 is
required. They will be removed once support for NumPy prior to
v1.17 is dropped.

These functions are copied from NumPy, but extended to work on NumPy arrays,
dask arrays and all xarray objects. You can find them in the ``xarray.ufuncs``
module:

:py:attr:`~ufuncs.angle`
:py:attr:`~ufuncs.arccos`
:py:attr:`~ufuncs.arccosh`
:py:attr:`~ufuncs.arcsin`
:py:attr:`~ufuncs.arcsinh`
:py:attr:`~ufuncs.arctan`
:py:attr:`~ufuncs.arctan2`
:py:attr:`~ufuncs.arctanh`
:py:attr:`~ufuncs.ceil`
:py:attr:`~ufuncs.conj`
:py:attr:`~ufuncs.copysign`
:py:attr:`~ufuncs.cos`
:py:attr:`~ufuncs.cosh`
:py:attr:`~ufuncs.deg2rad`
:py:attr:`~ufuncs.degrees`
:py:attr:`~ufuncs.exp`
:py:attr:`~ufuncs.expm1`
:py:attr:`~ufuncs.fabs`
:py:attr:`~ufuncs.fix`
:py:attr:`~ufuncs.floor`
:py:attr:`~ufuncs.fmax`
:py:attr:`~ufuncs.fmin`
:py:attr:`~ufuncs.fmod`
:py:attr:`~ufuncs.fmod`
:py:attr:`~ufuncs.frexp`
:py:attr:`~ufuncs.hypot`
:py:attr:`~ufuncs.imag`
:py:attr:`~ufuncs.iscomplex`
:py:attr:`~ufuncs.isfinite`
:py:attr:`~ufuncs.isinf`
:py:attr:`~ufuncs.isnan`
:py:attr:`~ufuncs.isreal`
:py:attr:`~ufuncs.ldexp`
:py:attr:`~ufuncs.log`
:py:attr:`~ufuncs.log10`
:py:attr:`~ufuncs.log1p`
:py:attr:`~ufuncs.log2`
:py:attr:`~ufuncs.logaddexp`
:py:attr:`~ufuncs.logaddexp2`
:py:attr:`~ufuncs.logical_and`
:py:attr:`~ufuncs.logical_not`
:py:attr:`~ufuncs.logical_or`
:py:attr:`~ufuncs.logical_xor`
:py:attr:`~ufuncs.maximum`
:py:attr:`~ufuncs.minimum`
:py:attr:`~ufuncs.nextafter`
:py:attr:`~ufuncs.rad2deg`
:py:attr:`~ufuncs.radians`
:py:attr:`~ufuncs.real`
:py:attr:`~ufuncs.rint`
:py:attr:`~ufuncs.sign`
:py:attr:`~ufuncs.signbit`
:py:attr:`~ufuncs.sin`
:py:attr:`~ufuncs.sinh`
:py:attr:`~ufuncs.sqrt`
:py:attr:`~ufuncs.square`
:py:attr:`~ufuncs.tan`
:py:attr:`~ufuncs.tanh`
:py:attr:`~ufuncs.trunc`

IO / Conversion
===============

Expand Down
3 changes: 3 additions & 0 deletions doc/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ Breaking changes
- Many arguments like ``keep_attrs``, ``axis``, and ``skipna`` are now keyword
only for all reduction operations like ``.mean``.
By `Deepak Cherian <https://github.com/dcherian>`_, `Jimmy Westling <https://github.com/illviljan>`_.
- Xarray's ufuncs have been removed, now that they can be replaced by numpy's ufuncs in all
supported versions of numpy.
By `Maximilian Roos <https://github.com/max-sixty>`_.

Deprecations
~~~~~~~~~~~~
Expand Down
3 changes: 1 addition & 2 deletions xarray/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from . import testing, tutorial, ufuncs
from . import testing, tutorial
from .backends.api import (
load_dataarray,
load_dataset,
Expand Down Expand Up @@ -53,7 +53,6 @@
# `mypy --strict` running in projects that import xarray.
__all__ = (
# Sub-packages
"ufuncs",
"testing",
"tutorial",
# Top-level functions
Expand Down
12 changes: 4 additions & 8 deletions xarray/tests/test_dask.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from packaging.version import Version

import xarray as xr
import xarray.ufuncs as xu
from xarray import DataArray, Dataset, Variable
from xarray.core import duck_array_ops
from xarray.core.pycompat import dask_version
Expand Down Expand Up @@ -265,18 +264,16 @@ def test_missing_methods(self):
except NotImplementedError as err:
assert "dask" in str(err)

@pytest.mark.filterwarnings("ignore::FutureWarning")
def test_univariate_ufunc(self):
u = self.eager_var
v = self.lazy_var
self.assertLazyAndAllClose(np.sin(u), xu.sin(v))
self.assertLazyAndAllClose(np.sin(u), np.sin(v))

@pytest.mark.filterwarnings("ignore::FutureWarning")
def test_bivariate_ufunc(self):
u = self.eager_var
v = self.lazy_var
self.assertLazyAndAllClose(np.maximum(u, 0), xu.maximum(v, 0))
self.assertLazyAndAllClose(np.maximum(u, 0), xu.maximum(0, v))
self.assertLazyAndAllClose(np.maximum(u, 0), np.maximum(v, 0))
self.assertLazyAndAllClose(np.maximum(u, 0), np.maximum(0, v))

def test_compute(self):
u = self.eager_var
Expand Down Expand Up @@ -605,11 +602,10 @@ def duplicate_and_merge(array):
actual = duplicate_and_merge(self.lazy_array)
self.assertLazyAndEqual(expected, actual)

@pytest.mark.filterwarnings("ignore::FutureWarning")
def test_ufuncs(self):
u = self.eager_array
v = self.lazy_array
self.assertLazyAndAllClose(np.sin(u), xu.sin(v))
self.assertLazyAndAllClose(np.sin(u), np.sin(v))

def test_where_dispatching(self):
a = np.arange(10)
Expand Down
12 changes: 3 additions & 9 deletions xarray/tests/test_sparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from packaging.version import Version

import xarray as xr
import xarray.ufuncs as xu
from xarray import DataArray, Variable
from xarray.core.pycompat import sparse_array_type, sparse_version

Expand Down Expand Up @@ -279,12 +278,12 @@ def test_unary_op(self):

@pytest.mark.filterwarnings("ignore::FutureWarning")
def test_univariate_ufunc(self):
assert_sparse_equal(np.sin(self.data), xu.sin(self.var).data)
assert_sparse_equal(np.sin(self.data), np.sin(self.var).data)

@pytest.mark.filterwarnings("ignore::FutureWarning")
def test_bivariate_ufunc(self):
assert_sparse_equal(np.maximum(self.data, 0), xu.maximum(self.var, 0).data)
assert_sparse_equal(np.maximum(self.data, 0), xu.maximum(0, self.var).data)
assert_sparse_equal(np.maximum(self.data, 0), np.maximum(self.var, 0).data)
assert_sparse_equal(np.maximum(self.data, 0), np.maximum(0, self.var).data)

def test_repr(self):
expected = dedent(
Expand Down Expand Up @@ -665,11 +664,6 @@ def test_stack(self):
roundtripped = stacked.unstack()
assert_identical(arr, roundtripped)

@pytest.mark.filterwarnings("ignore::FutureWarning")
def test_ufuncs(self):
x = self.sp_xr
assert_equal(np.sin(x), xu.sin(x))

def test_dataarray_repr(self):
a = xr.DataArray(
sparse.COO.from_numpy(np.ones(4)),
Expand Down
52 changes: 0 additions & 52 deletions xarray/tests/test_ufuncs.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import pickle

import numpy as np
import pytest

import xarray as xr
import xarray.ufuncs as xu

from . import assert_array_equal
from . import assert_identical as assert_identical_
Expand Down Expand Up @@ -158,52 +155,3 @@ def test_gufuncs():
fake_gufunc = mock.Mock(signature="(n)->()", autospec=np.sin)
with pytest.raises(NotImplementedError, match=r"generalized ufuncs"):
xarray_obj.__array_ufunc__(fake_gufunc, "__call__", xarray_obj)


def test_xarray_ufuncs_deprecation():
with pytest.warns(FutureWarning, match="xarray.ufuncs"):
xu.cos(xr.DataArray([0, 1]))

with assert_no_warnings():
xu.angle(xr.DataArray([0, 1]))


@pytest.mark.filterwarnings("ignore::RuntimeWarning")
@pytest.mark.parametrize(
"name",
[
name
for name in dir(xu)
if (
not name.startswith("_")
and hasattr(np, name)
and name not in ["print_function", "absolute_import", "division"]
)
],
)
def test_numpy_ufuncs(name, request):
x = xr.DataArray([1, 1])

np_func = getattr(np, name)
if hasattr(np_func, "nin") and np_func.nin == 2:
args = (x, x)
else:
args = (x,)

y = np_func(*args)

if name in ["angle", "iscomplex"]:
# these functions need to be handled with __array_function__ protocol
assert isinstance(y, np.ndarray)
elif name in ["frexp"]:
# np.frexp returns a tuple
assert not isinstance(y, xr.DataArray)
else:
assert isinstance(y, xr.DataArray)


@pytest.mark.filterwarnings("ignore:xarray.ufuncs")
def test_xarray_ufuncs_pickle():
a = 1.0
cos_pickled = pickle.loads(pickle.dumps(xu.cos))
assert_identical(cos_pickled(a), xu.cos(a))
Loading

0 comments on commit 33cdabd

Please sign in to comment.