Skip to content

Commit a26c816

Browse files
hollymandeldcheriankeewis
authored
support for additional scipy nd interpolants (#9599)
* nd interpolants added * remove reduce arg * docstring formatting * list of string args for method * moving list of interpolants * formatting * doc build issues * remove reduce from tests * removing other interpolants from test_interpolate_chunk_1d since cannot be 1d decomposed * nd_nd test update * formatting * scipy ref * docstrings * Update xarray/tests/test_interp.py Co-authored-by: Deepak Cherian <dcherian@users.noreply.github.com> * test method changes * formatting * fix typing * removing cubic from chunk 1d test because of timeout * rerun tests * try again * formatting * Skip fewer tests * skip quintic for high dim interp --------- Co-authored-by: Deepak Cherian <dcherian@users.noreply.github.com> Co-authored-by: Deepak Cherian <deepak@cherian.net> Co-authored-by: Justus Magin <keewis@users.noreply.github.com>
1 parent fad2773 commit a26c816

File tree

6 files changed

+323
-178
lines changed

6 files changed

+323
-178
lines changed

doc/user-guide/interpolation.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,11 @@ It is now possible to safely compute the difference ``other - interpolated``.
132132
Interpolation methods
133133
---------------------
134134

135-
We use :py:class:`scipy.interpolate.interp1d` for 1-dimensional interpolation.
135+
We use either :py:class:`scipy.interpolate.interp1d` or special interpolants from
136+
:py:class:`scipy.interpolate` for 1-dimensional interpolation (see :py:meth:`~xarray.Dataset.interp`).
136137
For multi-dimensional interpolation, an attempt is first made to decompose the
137138
interpolation in a series of 1-dimensional interpolations, in which case
138-
:py:class:`scipy.interpolate.interp1d` is used. If a decomposition cannot be
139+
the relevant 1-dimensional interpolator is used. If a decomposition cannot be
139140
made (e.g. with advanced interpolation), :py:func:`scipy.interpolate.interpn` is
140141
used.
141142

xarray/core/dataarray.py

Lines changed: 80 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2228,16 +2228,13 @@ def interp(
22282228
kwargs: Mapping[str, Any] | None = None,
22292229
**coords_kwargs: Any,
22302230
) -> Self:
2231-
"""Interpolate a DataArray onto new coordinates
2231+
"""
2232+
Interpolate a DataArray onto new coordinates.
2233+
2234+
Performs univariate or multivariate interpolation of a Dataset onto new coordinates,
2235+
utilizing either NumPy or SciPy interpolation routines.
22322236
2233-
Performs univariate or multivariate interpolation of a DataArray onto
2234-
new coordinates using scipy's interpolation routines. If interpolating
2235-
along an existing dimension, either :py:class:`scipy.interpolate.interp1d`
2236-
or a 1-dimensional scipy interpolator (e.g. :py:class:`scipy.interpolate.KroghInterpolator`)
2237-
is called. When interpolating along multiple existing dimensions, an
2238-
attempt is made to decompose the interpolation into multiple
2239-
1-dimensional interpolations. If this is possible, the 1-dimensional interpolator is called.
2240-
Otherwise, :py:func:`scipy.interpolate.interpn` is called.
2237+
Out-of-range values are filled with NaN, unless specified otherwise via `kwargs` to the numpy/scipy interpolant.
22412238
22422239
Parameters
22432240
----------
@@ -2246,16 +2243,9 @@ def interp(
22462243
New coordinate can be a scalar, array-like or DataArray.
22472244
If DataArrays are passed as new coordinates, their dimensions are
22482245
used for the broadcasting. Missing values are skipped.
2249-
method : {"linear", "nearest", "zero", "slinear", "quadratic", "cubic", "polynomial"}, default: "linear"
2250-
The method used to interpolate. The method should be supported by
2251-
the scipy interpolator:
2252-
2253-
- ``interp1d``: {"linear", "nearest", "zero", "slinear",
2254-
"quadratic", "cubic", "polynomial"}
2255-
- ``interpn``: {"linear", "nearest"}
2256-
2257-
If ``"polynomial"`` is passed, the ``order`` keyword argument must
2258-
also be provided.
2246+
method : { "linear", "nearest", "zero", "slinear", "quadratic", "cubic", \
2247+
"quintic", "polynomial", "pchip", "barycentric", "krogh", "akima", "makima" }
2248+
Interpolation method to use (see descriptions above).
22592249
assume_sorted : bool, default: False
22602250
If False, values of x can be in any order and they are sorted
22612251
first. If True, x has to be an array of monotonically increasing
@@ -2275,12 +2265,37 @@ def interp(
22752265
22762266
Notes
22772267
-----
2278-
scipy is required.
2268+
- SciPy is required for certain interpolation methods.
2269+
- When interpolating along multiple dimensions with methods `linear` and `nearest`,
2270+
the process attempts to decompose the interpolation into independent interpolations
2271+
along one dimension at a time.
2272+
- The specific interpolation method and dimensionality determine which
2273+
interpolant is used:
2274+
2275+
1. **Interpolation along one dimension of 1D data (`method='linear'`)**
2276+
- Uses :py:func:`numpy.interp`, unless `fill_value='extrapolate'` is provided via `kwargs`.
2277+
2278+
2. **Interpolation along one dimension of N-dimensional data (N ≥ 1)**
2279+
- Methods {"linear", "nearest", "zero", "slinear", "quadratic", "cubic", "quintic", "polynomial"}
2280+
use :py:func:`scipy.interpolate.interp1d`, unless conditions permit the use of :py:func:`numpy.interp`
2281+
(as in the case of `method='linear'` for 1D data).
2282+
- If `method='polynomial'`, the `order` keyword argument must also be provided.
2283+
2284+
3. **Special interpolants for interpolation along one dimension of N-dimensional data (N ≥ 1)**
2285+
- Depending on the `method`, the following interpolants from :py:class:`scipy.interpolate` are used:
2286+
- `"pchip"`: :py:class:`scipy.interpolate.PchipInterpolator`
2287+
- `"barycentric"`: :py:class:`scipy.interpolate.BarycentricInterpolator`
2288+
- `"krogh"`: :py:class:`scipy.interpolate.KroghInterpolator`
2289+
- `"akima"` or `"makima"`: :py:class:`scipy.interpolate.Akima1dInterpolator`
2290+
(`makima` is handled by passing the `makima` flag).
2291+
2292+
4. **Interpolation along multiple dimensions of multi-dimensional data**
2293+
- Uses :py:func:`scipy.interpolate.interpn` for methods {"linear", "nearest", "slinear",
2294+
"cubic", "quintic", "pchip"}.
22792295
22802296
See Also
22812297
--------
2282-
scipy.interpolate.interp1d
2283-
scipy.interpolate.interpn
2298+
:mod:`scipy.interpolate`
22842299
22852300
:doc:`xarray-tutorial:fundamentals/02.2_manipulating_dimensions`
22862301
Tutorial material on manipulating data resolution using :py:func:`~xarray.DataArray.interp`
@@ -2376,43 +2391,67 @@ def interp_like(
23762391
"""Interpolate this object onto the coordinates of another object,
23772392
filling out of range values with NaN.
23782393
2379-
If interpolating along a single existing dimension,
2380-
:py:class:`scipy.interpolate.interp1d` is called. When interpolating
2381-
along multiple existing dimensions, an attempt is made to decompose the
2382-
interpolation into multiple 1-dimensional interpolations. If this is
2383-
possible, :py:class:`scipy.interpolate.interp1d` is called. Otherwise,
2384-
:py:func:`scipy.interpolate.interpn` is called.
2385-
23862394
Parameters
23872395
----------
23882396
other : Dataset or DataArray
23892397
Object with an 'indexes' attribute giving a mapping from dimension
23902398
names to an 1d array-like, which provides coordinates upon
23912399
which to index the variables in this dataset. Missing values are skipped.
2392-
method : {"linear", "nearest", "zero", "slinear", "quadratic", "cubic", "polynomial"}, default: "linear"
2393-
The method used to interpolate. The method should be supported by
2394-
the scipy interpolator:
2395-
2396-
- {"linear", "nearest", "zero", "slinear", "quadratic", "cubic",
2397-
"polynomial"} when ``interp1d`` is called.
2398-
- {"linear", "nearest"} when ``interpn`` is called.
2399-
2400-
If ``"polynomial"`` is passed, the ``order`` keyword argument must
2401-
also be provided.
2400+
method : { "linear", "nearest", "zero", "slinear", "quadratic", "cubic", \
2401+
"quintic", "polynomial", "pchip", "barycentric", "krogh", "akima", "makima" }
2402+
Interpolation method to use (see descriptions above).
24022403
assume_sorted : bool, default: False
24032404
If False, values of coordinates that are interpolated over can be
24042405
in any order and they are sorted first. If True, interpolated
24052406
coordinates are assumed to be an array of monotonically increasing
24062407
values.
24072408
kwargs : dict, optional
2408-
Additional keyword passed to scipy's interpolator.
2409+
Additional keyword arguments passed to the interpolant.
24092410
24102411
Returns
24112412
-------
24122413
interpolated : DataArray
24132414
Another dataarray by interpolating this dataarray's data along the
24142415
coordinates of the other object.
24152416
2417+
Notes
2418+
-----
2419+
- scipy is required.
2420+
- If the dataarray has object-type coordinates, reindex is used for these
2421+
coordinates instead of the interpolation.
2422+
- When interpolating along multiple dimensions with methods `linear` and `nearest`,
2423+
the process attempts to decompose the interpolation into independent interpolations
2424+
along one dimension at a time.
2425+
- The specific interpolation method and dimensionality determine which
2426+
interpolant is used:
2427+
2428+
1. **Interpolation along one dimension of 1D data (`method='linear'`)**
2429+
- Uses :py:func:`numpy.interp`, unless `fill_value='extrapolate'` is provided via `kwargs`.
2430+
2431+
2. **Interpolation along one dimension of N-dimensional data (N ≥ 1)**
2432+
- Methods {"linear", "nearest", "zero", "slinear", "quadratic", "cubic", "quintic", "polynomial"}
2433+
use :py:func:`scipy.interpolate.interp1d`, unless conditions permit the use of :py:func:`numpy.interp`
2434+
(as in the case of `method='linear'` for 1D data).
2435+
- If `method='polynomial'`, the `order` keyword argument must also be provided.
2436+
2437+
3. **Special interpolants for interpolation along one dimension of N-dimensional data (N ≥ 1)**
2438+
- Depending on the `method`, the following interpolants from :py:class:`scipy.interpolate` are used:
2439+
- `"pchip"`: :py:class:`scipy.interpolate.PchipInterpolator`
2440+
- `"barycentric"`: :py:class:`scipy.interpolate.BarycentricInterpolator`
2441+
- `"krogh"`: :py:class:`scipy.interpolate.KroghInterpolator`
2442+
- `"akima"` or `"makima"`: :py:class:`scipy.interpolate.Akima1dInterpolator`
2443+
(`makima` is handled by passing the `makima` flag).
2444+
2445+
4. **Interpolation along multiple dimensions of multi-dimensional data**
2446+
- Uses :py:func:`scipy.interpolate.interpn` for methods {"linear", "nearest", "slinear",
2447+
"cubic", "quintic", "pchip"}.
2448+
2449+
See Also
2450+
--------
2451+
:func:`DataArray.interp`
2452+
:func:`DataArray.reindex_like`
2453+
:mod:`scipy.interpolate`
2454+
24162455
Examples
24172456
--------
24182457
>>> data = np.arange(12).reshape(4, 3)
@@ -2468,18 +2507,8 @@ def interp_like(
24682507
Coordinates:
24692508
* x (x) int64 32B 10 20 30 40
24702509
* y (y) int64 24B 70 80 90
2471-
2472-
Notes
2473-
-----
2474-
scipy is required.
2475-
If the dataarray has object-type coordinates, reindex is used for these
2476-
coordinates instead of the interpolation.
2477-
2478-
See Also
2479-
--------
2480-
DataArray.interp
2481-
DataArray.reindex_like
24822510
"""
2511+
24832512
if self.dtype.kind not in "uifc":
24842513
raise TypeError(
24852514
f"interp only works for a numeric type array. Given {self.dtype}."

0 commit comments

Comments
 (0)