pydata / pydata/xarray

Interpolation - Support extrapolation method "clip"

Open
#3,962 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement topic-documentation topic-interpolation
Dominant language
Python
Stars
4.2k
Forks
1.4k
Avg merge
2d 15h
Merged PRs (30d)
14

Description

Hello,

I would like an option in da.interp() that instead of returning NaNs during extrapolation returns the data corresponding to the end of the breakpoint data set range.

One way to do this is to limit the new coordinates to the array coordinates minimum and maximum value, I did a simple example with this solution down below.
I think this is a rather safe way as we are just modifying the inputs to all the various interpolation classes that xarray is using at the moment.
But it does look a little weird when printing the extrapolated value, the coordinates shows the limited value instead of the requested coordinates. Maybe this can be handled elegantly somewhere in the source code?

MATLAB uses this quite frequently in their interpolation functions:

MCVE Code Sample
import numpy as np
import xarray as xr


def interp(da, coords, extrapolation='clip'):
    """
    Linear interpolation that clips the inputs to the coords min and max value.

    Parameters
    ----------
    da : DataArray
        DataArray to interpolate.
    coords : dict
        Coordinates for the interpolated value.
    """
    if extrapolation == 'clip':
        for k, v in da.coords.items():
            coords[k] = np.maximum(coords[k], np.min(v.values))
            coords[k] = np.minimum(coords[k], np.max(v.values))

    return da.interp(coords)


# Create coordinates:
x = np.linspace(1000, 6000, 4)
y = np.linspace(100, 1200, 3)

# Create data:
X = np.meshgrid(*[x, y], indexing='ij')
data = X[0] * X[1]

# Create DataArray:
da = xr.DataArray(data=data, coords=[('x', x), ('y', y)], name='data')

# Attempt to extrapolate:
datai = interp(da, {'x': 7000, 'y': 375})
Expected Output
print(datai)
<xarray.DataArray 'data' ()>
array(2250000.)
Coordinates:
    x        float64 6e+03
    y        float64 375.0
Versions
Output of `xr.show_versions()`

INSTALLED VERSIONS

commit: None
python: 3.7.7 (default, Mar 23 2020, 23:19:08) [MSC v.1916 64 bit (AMD64)]
python-bits: 64
OS: Windows
OS-release: 10
machine: AMD64
processor: Intel64 Family 6 Model 58 Stepping 9, GenuineIntel
byteorder: little
LC_ALL: None
LANG: en
LOCALE: None.None
libhdf5: 1.10.4
libnetcdf: None

xarray: 0.15.0
pandas: 1.0.3
numpy: 1.18.1
scipy: 1.4.1
netCDF4: None
pydap: None
h5netcdf: None
h5py: 2.10.0
Nio: None
zarr: None
cftime: None
nc_time_axis: None
PseudoNetCDF: None
rasterio: None
cfgrib: None
iris: None
bottleneck: 1.3.2
dask: 2.13.0
distributed: 2.13.0
matplotlib: 3.1.3
cartopy: None
seaborn: 0.10.0
numbagg: None
setuptools: 46.1.3.post20200330
pip: 20.0.2
conda: 4.8.3
pytest: 5.4.1
IPython: 7.13.0
sphinx: 2.4.4

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the da.interp() entry point and reproduce the MCVE with coordinates outside the breakpoint range. Define how a "clip" option should affect extrapolated values while preserving the requested output coordinates, then verify that out-of-range interpolation returns the corresponding endpoint values instead of NaNs.

Written by the indexing model from the issue text.

Assessment

Tech stack
numpy, python
Domain
data
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.