diff --git a/ci/requirements/py36-bare-minimum.yml b/ci/requirements/py36-bare-minimum.yml
index 05186bc8748..8b604ce02dd 100644
--- a/ci/requirements/py36-bare-minimum.yml
+++ b/ci/requirements/py36-bare-minimum.yml
@@ -7,5 +7,5 @@ dependencies:
- pytest
- pytest-cov
- pytest-env
- - numpy=1.14
- - pandas=0.24
+ - numpy=1.15
+ - pandas=0.25
diff --git a/ci/requirements/py36-min-all-deps.yml b/ci/requirements/py36-min-all-deps.yml
index ea707461013..dc77e232dea 100644
--- a/ci/requirements/py36-min-all-deps.yml
+++ b/ci/requirements/py36-min-all-deps.yml
@@ -29,8 +29,8 @@ dependencies:
- nc-time-axis=1.2
- netcdf4=1.4
- numba=0.44
- - numpy=1.14
- - pandas=0.24
+ - numpy=1.15
+ - pandas=0.25
# - pint # See py36-min-nep18.yml
- pip
- pseudonetcdf=3.0
@@ -40,7 +40,7 @@ dependencies:
- pytest-cov
- pytest-env
- rasterio=1.0
- - scipy=1.0 # Policy allows for 1.2, but scipy>=1.1 breaks numpy=1.14
+ - scipy=1.3
- seaborn=0.9
# - sparse # See py36-min-nep18.yml
- toolz=0.10
diff --git a/ci/requirements/py36-min-nep18.yml b/ci/requirements/py36-min-nep18.yml
index fc9523ce249..8fe7644d626 100644
--- a/ci/requirements/py36-min-nep18.yml
+++ b/ci/requirements/py36-min-nep18.yml
@@ -9,7 +9,7 @@ dependencies:
- dask=2.4
- distributed=2.4
- numpy=1.17
- - pandas=0.24
+ - pandas=0.25
- pint=0.9 # Actually not enough as it doesn't implement __array_function__yet!
- pytest
- pytest-cov
diff --git a/doc/installing.rst b/doc/installing.rst
index 219cf109efe..5c39f9a3c49 100644
--- a/doc/installing.rst
+++ b/doc/installing.rst
@@ -7,8 +7,8 @@ Required dependencies
---------------------
- Python (3.6 or later)
-- `numpy `__ (1.14 or later)
-- `pandas `__ (0.24 or later)
+- `numpy `__ (1.15 or later)
+- `pandas `__ (0.25 or later)
Optional dependencies
---------------------
diff --git a/doc/whats-new.rst b/doc/whats-new.rst
index c310d53190d..9fbeaa95055 100644
--- a/doc/whats-new.rst
+++ b/doc/whats-new.rst
@@ -21,7 +21,13 @@ v0.15.0 (unreleased)
Breaking changes
~~~~~~~~~~~~~~~~
-- Bumped minimum ``dask`` version to 2.2.
+- Bumped minimum tested versions for dependencies:
+ - numpy 1.15
+ - pandas 0.25
+ - dask 2.2
+ - distributed 2.2
+ - scipy 1.3
+
- Remove ``compat`` and ``encoding`` kwargs from ``DataArray``, which
have been deprecated since 0.12. (:pull:`3650`).
Instead, specify the encoding when writing to disk or set
diff --git a/setup.cfg b/setup.cfg
index ec0fd28ef73..e336f46e68c 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -79,8 +79,8 @@ zip_safe = False # https://mypy.readthedocs.io/en/latest/installed_packages.htm
include_package_data = True
python_requires = >=3.6
install_requires =
- numpy >= 1.14
- pandas >= 0.24
+ numpy >= 1.15
+ pandas >= 0.25
setup_requires = setuptools_scm
[options.package_data]
diff --git a/xarray/core/dataarray.py b/xarray/core/dataarray.py
index 0e67a791834..4fc6773c459 100644
--- a/xarray/core/dataarray.py
+++ b/xarray/core/dataarray.py
@@ -2969,7 +2969,7 @@ def quantile(
See Also
--------
- numpy.nanpercentile, pandas.Series.quantile, Dataset.quantile
+ numpy.nanquantile, pandas.Series.quantile, Dataset.quantile
Examples
--------
diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py
index 82ddc8a535f..5ac79999795 100644
--- a/xarray/core/dataset.py
+++ b/xarray/core/dataset.py
@@ -4466,12 +4466,7 @@ def _set_sparse_data_from_dataframe(
idx = dataframe.index
if isinstance(idx, pd.MultiIndex):
- try:
- codes = idx.codes
- except AttributeError:
- # deprecated since pandas 0.24
- codes = idx.labels
- coords = np.stack([np.asarray(code) for code in codes], axis=0)
+ coords = np.stack([np.asarray(code) for code in idx.codes], axis=0)
is_sorted = idx.is_lexsorted
else:
coords = np.arange(idx.size).reshape(1, -1)
@@ -5171,7 +5166,7 @@ def quantile(
See Also
--------
- numpy.nanpercentile, pandas.Series.quantile, DataArray.quantile
+ numpy.nanquantile, pandas.Series.quantile, DataArray.quantile
Examples
--------
diff --git a/xarray/core/groupby.py b/xarray/core/groupby.py
index 5b52f48413d..f2a9ebac6eb 100644
--- a/xarray/core/groupby.py
+++ b/xarray/core/groupby.py
@@ -595,7 +595,7 @@ def quantile(self, q, dim=None, interpolation="linear", keep_attrs=None):
See Also
--------
- numpy.nanpercentile, pandas.Series.quantile, Dataset.quantile,
+ numpy.nanquantile, pandas.Series.quantile, Dataset.quantile,
DataArray.quantile
Examples
diff --git a/xarray/core/nputils.py b/xarray/core/nputils.py
index 3fe2c254b0f..dba67174fc1 100644
--- a/xarray/core/nputils.py
+++ b/xarray/core/nputils.py
@@ -3,6 +3,8 @@
import numpy as np
import pandas as pd
+from numpy.core.multiarray import normalize_axis_index
+
try:
import bottleneck as bn
@@ -13,15 +15,6 @@
_USE_BOTTLENECK = False
-def _validate_axis(data, axis):
- ndim = data.ndim
- if not -ndim <= axis < ndim:
- raise IndexError(f"axis {axis!r} out of bounds [-{ndim}, {ndim})")
- if axis < 0:
- axis += ndim
- return axis
-
-
def _select_along_axis(values, idx, axis):
other_ind = np.ix_(*[np.arange(s) for s in idx.shape])
sl = other_ind[:axis] + (idx,) + other_ind[axis:]
@@ -29,13 +22,13 @@ def _select_along_axis(values, idx, axis):
def nanfirst(values, axis):
- axis = _validate_axis(values, axis)
+ axis = normalize_axis_index(axis, values.ndim)
idx_first = np.argmax(~pd.isnull(values), axis=axis)
return _select_along_axis(values, idx_first, axis)
def nanlast(values, axis):
- axis = _validate_axis(values, axis)
+ axis = normalize_axis_index(axis, values.ndim)
rev = (slice(None),) * axis + (slice(None, None, -1),)
idx_last = -1 - np.argmax(~pd.isnull(values)[rev], axis=axis)
return _select_along_axis(values, idx_last, axis)
@@ -186,7 +179,7 @@ def _rolling_window(a, window, axis=-1):
This function is taken from https://github.com/numpy/numpy/pull/31
but slightly modified to accept axis option.
"""
- axis = _validate_axis(a, axis)
+ axis = normalize_axis_index(axis, a.ndim)
a = np.swapaxes(a, axis, -1)
if window < 1:
diff --git a/xarray/core/variable.py b/xarray/core/variable.py
index 0a9d0767b77..74d5d57e6f6 100644
--- a/xarray/core/variable.py
+++ b/xarray/core/variable.py
@@ -1722,7 +1722,7 @@ def quantile(self, q, dim=None, interpolation="linear", keep_attrs=None):
See Also
--------
- numpy.nanpercentile, pandas.Series.quantile, Dataset.quantile,
+ numpy.nanquantile, pandas.Series.quantile, Dataset.quantile,
DataArray.quantile
"""
@@ -1734,10 +1734,6 @@ def quantile(self, q, dim=None, interpolation="linear", keep_attrs=None):
scalar = utils.is_scalar(q)
q = np.atleast_1d(np.asarray(q, dtype=np.float64))
- # TODO: remove once numpy >= 1.15.0 is the minimum requirement
- if np.count_nonzero(q < 0.0) or np.count_nonzero(q > 1.0):
- raise ValueError("Quantiles must be in the range [0, 1]")
-
if dim is None:
dim = self.dims
@@ -1746,9 +1742,7 @@ def quantile(self, q, dim=None, interpolation="linear", keep_attrs=None):
def _wrapper(npa, **kwargs):
# move quantile axis to end. required for apply_ufunc
-
- # TODO: use np.nanquantile once numpy >= 1.15.0 is the minimum requirement
- return np.moveaxis(np.nanpercentile(npa, **kwargs), 0, -1)
+ return np.moveaxis(np.nanquantile(npa, **kwargs), 0, -1)
axis = np.arange(-1, -1 * len(dim) - 1, -1)
result = apply_ufunc(
@@ -1760,7 +1754,7 @@ def _wrapper(npa, **kwargs):
output_dtypes=[np.float64],
output_sizes={"quantile": len(q)},
dask="parallelized",
- kwargs={"q": q * 100, "axis": axis, "interpolation": interpolation},
+ kwargs={"q": q, "axis": axis, "interpolation": interpolation},
)
# for backward compatibility
diff --git a/xarray/plot/utils.py b/xarray/plot/utils.py
index c900dfeff3e..6eec7c6b433 100644
--- a/xarray/plot/utils.py
+++ b/xarray/plot/utils.py
@@ -583,10 +583,6 @@ def _add_colorbar(primitive, ax, cbar_ax, cbar_kwargs, cmap_params):
def _rescale_imshow_rgb(darray, vmin, vmax, robust):
assert robust or vmin is not None or vmax is not None
- # TODO: remove when min numpy version is bumped to 1.13
- # There's a cyclic dependency via DataArray, so we can't import from
- # xarray.ufuncs in global scope.
- from xarray.ufuncs import maximum, minimum
# Calculate vmin and vmax automatically for `robust=True`
if robust:
@@ -615,9 +611,7 @@ def _rescale_imshow_rgb(darray, vmin, vmax, robust):
# After scaling, downcast to 32-bit float. This substantially reduces
# memory usage after we hand `darray` off to matplotlib.
darray = ((darray.astype("f8") - vmin) / (vmax - vmin)).astype("f4")
- with warnings.catch_warnings():
- warnings.filterwarnings("ignore", "xarray.ufuncs", PendingDeprecationWarning)
- return minimum(maximum(darray, 0), 1)
+ return np.minimum(np.maximum(darray, 0), 1)
def _update_axes(
diff --git a/xarray/tests/test_dataarray.py b/xarray/tests/test_dataarray.py
index 962be7548bc..b9b719e8af9 100644
--- a/xarray/tests/test_dataarray.py
+++ b/xarray/tests/test_dataarray.py
@@ -80,7 +80,7 @@ def test_repr_multiindex(self):
assert expected == repr(self.mda)
@pytest.mark.skipif(
- LooseVersion(np.__version__) < "1.15",
+ LooseVersion(np.__version__) < "1.16",
reason="old versions of numpy have different printing behavior",
)
def test_repr_multiindex_long(self):
diff --git a/xarray/tests/test_units.py b/xarray/tests/test_units.py
index 6f9128839a7..d98e5e23516 100644
--- a/xarray/tests/test_units.py
+++ b/xarray/tests/test_units.py
@@ -1838,7 +1838,10 @@ def test_squeeze(self, dtype):
"func",
(
method("coarsen", windows={"y": 2}, func=np.mean),
- method("quantile", q=[0.25, 0.75]),
+ pytest.param(
+ method("quantile", q=[0.25, 0.75]),
+ marks=pytest.mark.xfail(reason="nanquantile not implemented"),
+ ),
pytest.param(
method("rank", dim="x"),
marks=pytest.mark.xfail(reason="rank not implemented for non-ndarray"),
@@ -3401,7 +3404,10 @@ def test_stacking_reordering(self, func, dtype):
method("diff", dim="x"),
method("differentiate", coord="x"),
method("integrate", dim="x"),
- method("quantile", q=[0.25, 0.75]),
+ pytest.param(
+ method("quantile", q=[0.25, 0.75]),
+ marks=pytest.mark.xfail(reason="nanquantile not implemented"),
+ ),
method("reduce", func=np.sum, dim="x"),
pytest.param(
lambda x: x.dot(x),
@@ -3491,7 +3497,10 @@ def test_resample(self, dtype):
method("assign_coords", z=(["x"], np.arange(5) * unit_registry.s)),
method("first"),
method("last"),
- method("quantile", q=np.array([0.25, 0.5, 0.75]), dim="x"),
+ pytest.param(
+ method("quantile", q=[0.25, 0.5, 0.75], dim="x"),
+ marks=pytest.mark.xfail(reason="nanquantile not implemented"),
+ ),
),
ids=repr,
)
@@ -4929,7 +4938,10 @@ def test_reindex_like(self, unit, error, dtype):
method("diff", dim="x"),
method("differentiate", coord="x"),
method("integrate", coord="x"),
- method("quantile", q=[0.25, 0.75]),
+ pytest.param(
+ method("quantile", q=[0.25, 0.75]),
+ marks=pytest.mark.xfail(reason="nanquantile not implemented"),
+ ),
method("reduce", func=np.sum, dim="x"),
method("map", np.fabs),
),
@@ -5039,7 +5051,10 @@ def test_resample(self, dtype):
method("assign_coords", v=("x", np.arange(10) * unit_registry.s)),
method("first"),
method("last"),
- method("quantile", q=[0.25, 0.5, 0.75], dim="x"),
+ pytest.param(
+ method("quantile", q=[0.25, 0.5, 0.75], dim="x"),
+ marks=pytest.mark.xfail(reason="nanquantile not implemented"),
+ ),
),
ids=repr,
)