diff --git a/doc/user-guide/interpolation.rst b/doc/user-guide/interpolation.rst index 73c0b312241..2dc47e9f591 100644 --- a/doc/user-guide/interpolation.rst +++ b/doc/user-guide/interpolation.rst @@ -132,8 +132,12 @@ It is now possible to safely compute the difference ``other - interpolated``. Interpolation methods --------------------- -We use :py:class:`scipy.interpolate.interp1d` for 1-dimensional interpolation and -:py:func:`scipy.interpolate.interpn` for multi-dimensional interpolation. +We use :py:class:`scipy.interpolate.interp1d` for 1-dimensional interpolation. +For multi-dimensional interpolation, an attempt is first made to decompose the +interpolation in a series of 1-dimensional interpolations, in which case +:py:class:`scipy.interpolate.interp1d` is used. If a decomposition cannot be +made (e.g. with advanced interpolation), :py:func:`scipy.interpolate.interpn` is +used. The interpolation method can be specified by the optional ``method`` argument. @@ -165,7 +169,9 @@ Additional keyword arguments can be passed to scipy's functions. [("time", np.arange(4)), ("space", [0.1, 0.2, 0.3])], ) - da.interp(time=4, space=np.linspace(-0.1, 0.5, 10), kwargs={"fill_value": None}) + da.interp( + time=4, space=np.linspace(-0.1, 0.5, 10), kwargs={"fill_value": "extrapolate"} + ) Advanced Interpolation @@ -198,23 +204,28 @@ For example: y = xr.DataArray([0.1, 0.2, 0.3], dims="z") da.sel(x=x, y=y) - # advanced interpolation - x = xr.DataArray([0.5, 1.5, 2.5], dims="z") - y = xr.DataArray([0.15, 0.25, 0.35], dims="z") + # advanced interpolation, without extrapolation + x = xr.DataArray([0.5, 1.5, 2.5, 3.5], dims="z") + y = xr.DataArray([0.15, 0.25, 0.35, 0.45], dims="z") da.interp(x=x, y=y) where values on the original coordinates -``(x, y) = ((0.5, 0.15), (1.5, 0.25), (2.5, 0.35))`` are obtained by the -2-dimensional interpolation and mapped along a new dimension ``z``. +``(x, y) = ((0.5, 0.15), (1.5, 0.25), (2.5, 0.35), (3.5, 0.45))`` are obtained +by the 2-dimensional interpolation and mapped along a new dimension ``z``. Since +no keyword arguments are passed to the interpolation routine, no extrapolation +is performed resulting in a ``nan`` value. If you want to add a coordinate to the new dimension ``z``, you can supply -:py:class:`~xarray.DataArray` s with a coordinate, +:py:class:`~xarray.DataArray` s with a coordinate. Extrapolation can be achieved +by passing additional arguments to SciPy's ``interpnd`` function, .. ipython:: python - x = xr.DataArray([0.5, 1.5, 2.5], dims="z", coords={"z": ["a", "b", "c"]}) - y = xr.DataArray([0.15, 0.25, 0.35], dims="z", coords={"z": ["a", "b", "c"]}) - da.interp(x=x, y=y) + x = xr.DataArray([0.5, 1.5, 2.5, 3.5], dims="z", coords={"z": ["a", "b", "c", "d"]}) + y = xr.DataArray( + [0.15, 0.25, 0.35, 0.45], dims="z", coords={"z": ["a", "b", "c", "d"]} + ) + da.interp(x=x, y=y, kwargs={"fill_value": None}) For the details of the advanced indexing, see :ref:`more advanced indexing `. diff --git a/xarray/core/dataarray.py b/xarray/core/dataarray.py index 0341d84b661..ee4516147de 100644 --- a/xarray/core/dataarray.py +++ b/xarray/core/dataarray.py @@ -1758,29 +1758,42 @@ def interp( kwargs: Mapping[str, Any] | None = None, **coords_kwargs: Any, ) -> T_DataArray: - """Multidimensional interpolation of variables. + """Interpolate a DataArray onto new coordinates + + Performs univariate or multivariate interpolation of a DataArray onto + new coordinates using scipy's interpolation routines. If interpolating + along an existing dimension, :py:class:`scipy.interpolate.interp1d` is + called. When interpolating along multiple existing dimensions, an + attempt is made to decompose the interpolation into multiple + 1-dimensional interpolations. If this is possible, + :py:class:`scipy.interpolate.interp1d` is called. Otherwise, + :py:func:`scipy.interpolate.interpn` is called. Parameters ---------- coords : dict, optional Mapping from dimension names to the new coordinates. - New coordinate can be an scalar, array-like or DataArray. + New coordinate can be a scalar, array-like or DataArray. If DataArrays are passed as new coordinates, their dimensions are used for the broadcasting. Missing values are skipped. - method : {"linear", "nearest", "zero", "slinear", "quadratic", "cubic"}, default: "linear" - The method used to interpolate. Choose from + method : {"linear", "nearest", "zero", "slinear", "quadratic", "cubic", "polynomial"}, default: "linear" + The method used to interpolate. The method should be supported by + the scipy interpolator: - - {"linear", "nearest"} for multidimensional array, - - {"linear", "nearest", "zero", "slinear", "quadratic", "cubic"} for 1-dimensional array. + - ``interp1d``: {"linear", "nearest", "zero", "slinear", + "quadratic", "cubic", "polynomial"} + - ``interpn``: {"linear", "nearest"} + If ``"polynomial"`` is passed, the ``order`` keyword argument must + also be provided. assume_sorted : bool, default: False If False, values of x can be in any order and they are sorted first. If True, x has to be an array of monotonically increasing values. kwargs : dict-like or None, default: None Additional keyword arguments passed to scipy's interpolator. Valid - options and their behavior depend on if 1-dimensional or - multi-dimensional interpolation is used. + options and their behavior depend whether ``interp1d`` or + ``interpn`` is used. **coords_kwargs : {dim: coordinate, ...}, optional The keyword arguments form of ``coords``. One of coords or coords_kwargs must be provided. @@ -1891,18 +1904,29 @@ def interp_like( """Interpolate this object onto the coordinates of another object, filling out of range values with NaN. + If interpolating along a single existing dimension, + :py:class:`scipy.interpolate.interp1d` is called. When interpolating + along multiple existing dimensions, an attempt is made to decompose the + interpolation into multiple 1-dimensional interpolations. If this is + possible, :py:class:`scipy.interpolate.interp1d` is called. Otherwise, + :py:func:`scipy.interpolate.interpn` is called. + Parameters ---------- other : Dataset or DataArray Object with an 'indexes' attribute giving a mapping from dimension names to an 1d array-like, which provides coordinates upon which to index the variables in this dataset. Missing values are skipped. - method : {"linear", "nearest", "zero", "slinear", "quadratic", "cubic"}, default: "linear" - The method used to interpolate. Choose from + method : {"linear", "nearest", "zero", "slinear", "quadratic", "cubic", "polynomial"}, default: "linear" + The method used to interpolate. The method should be supported by + the scipy interpolator: - - {"linear", "nearest"} for multidimensional array, - - {"linear", "nearest", "zero", "slinear", "quadratic", "cubic"} for 1-dimensional array. + - {"linear", "nearest", "zero", "slinear", "quadratic", "cubic", + "polynomial"} when ``interp1d`` is called. + - {"linear", "nearest"} when ``interpn`` is called. + If ``"polynomial"`` is passed, the ``order`` keyword argument must + also be provided. assume_sorted : bool, default: False If False, values of coordinates that are interpolated over can be in any order and they are sorted first. If True, interpolated diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index 084437e102c..38e4d2eadef 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -3044,7 +3044,16 @@ def interp( method_non_numeric: str = "nearest", **coords_kwargs: Any, ) -> Dataset: - """Multidimensional interpolation of Dataset. + """Interpolate a Dataset onto new coordinates + + Performs univariate or multivariate interpolation of a Dataset onto + new coordinates using scipy's interpolation routines. If interpolating + along an existing dimension, :py:class:`scipy.interpolate.interp1d` is + called. When interpolating along multiple existing dimensions, an + attempt is made to decompose the interpolation into multiple + 1-dimensional interpolations. If this is possible, + :py:class:`scipy.interpolate.interp1d` is called. Otherwise, + :py:func:`scipy.interpolate.interpn` is called. Parameters ---------- @@ -3054,9 +3063,15 @@ def interp( If DataArrays are passed as new coordinates, their dimensions are used for the broadcasting. Missing values are skipped. method : str, optional - {"linear", "nearest"} for multidimensional array, - {"linear", "nearest", "zero", "slinear", "quadratic", "cubic"} - for 1-dimensional array. "linear" is used by default. + The method used to interpolate. The method should be supported by + the scipy interpolator: + + - ``interp1d``: {"linear", "nearest", "zero", "slinear", + "quadratic", "cubic", "polynomial"} + - ``interpn``: {"linear", "nearest"} + + If ``"polynomial"`` is passed, the ``order`` keyword argument must + also be provided. assume_sorted : bool, optional If False, values of coordinates that are interpolated over can be in any order and they are sorted first. If True, interpolated @@ -3064,8 +3079,8 @@ def interp( values. kwargs : dict, optional Additional keyword arguments passed to scipy's interpolator. Valid - options and their behavior depend on if 1-dimensional or - multi-dimensional interpolation is used. + options and their behavior depend whether ``interp1d`` or + ``interpn`` is used. method_non_numeric : {"nearest", "pad", "ffill", "backfill", "bfill"}, optional Method for non-numeric types. Passed on to :py:meth:`Dataset.reindex`. ``"nearest"`` is used by default. @@ -3307,6 +3322,13 @@ def interp_like( """Interpolate this object onto the coordinates of another object, filling the out of range values with NaN. + If interpolating along a single existing dimension, + :py:class:`scipy.interpolate.interp1d` is called. When interpolating + along multiple existing dimensions, an attempt is made to decompose the + interpolation into multiple 1-dimensional interpolations. If this is + possible, :py:class:`scipy.interpolate.interp1d` is called. Otherwise, + :py:func:`scipy.interpolate.interpn` is called. + Parameters ---------- other : Dataset or DataArray @@ -3314,9 +3336,15 @@ def interp_like( names to an 1d array-like, which provides coordinates upon which to index the variables in this dataset. Missing values are skipped. method : str, optional - {"linear", "nearest"} for multidimensional array, - {"linear", "nearest", "zero", "slinear", "quadratic", "cubic"} - for 1-dimensional array. 'linear' is used by default. + The method used to interpolate. The method should be supported by + the scipy interpolator: + + - {"linear", "nearest", "zero", "slinear", "quadratic", "cubic", + "polynomial"} when ``interp1d`` is called. + - {"linear", "nearest"} when ``interpn`` is called. + + If ``"polynomial"`` is passed, the ``order`` keyword argument must + also be provided. assume_sorted : bool, optional If False, values of coordinates that are interpolated over can be in any order and they are sorted first. If True, interpolated