小能豆

Numpy scipy 2d interpolation for linear piecewise data

py

I have the points:

points = np.array([[0, 105],[5000, 105],[0, 135],[5000, 135],[0, 165],[5000, 165]])

and values

values = np.array([[300, 380, 300, 390, 300, 400]]).transpose()

with the inputs I’m trying to interpolate for

xi = np.array([[2500, 105],[2500, 125],[2500, 135],[2500, 150],[2500, 165]])

with expected result for bilinear interpolation (ref: https://en.wikipedia.org/wiki/Bilinear_interpolation)

[340, 343.3333, 345, 347.5, 350]

My working for the second example using bilinear interpolation

x1=2500, y1=105 giving z1=340
x2=2500, y2=135 giving z2=345
Hence for x3=2500, y3=125 gives z3=343.3333

however, with

gd = griddata(points, values, xi, method='linear', rescale=True)

I’m getting the result

[340, 345, 345, 345, 350]

I must be missing something simple here, but have gotten nowhere trying multiple different approaches.


阅读 66

收藏
2023-11-23

共1个答案

小能豆

The discrepancy you’re observing is likely due to how the griddata function handles points that fall outside the convex hull of the input points. By default, griddata performs extrapolation, and it seems to be causing the values for points outside the convex hull to be extrapolated based on the nearest values inside the convex hull.

To achieve bilinear interpolation behavior similar to your manual calculation, you can set the fill_value parameter of the griddata function to np.nan, and then use np.nanmean to compute the mean value excluding any np.nan values. Here’s how you can modify your code:

from scipy.interpolate import griddata
import numpy as np

points = np.array([[0, 105],[5000, 105],[0, 135],[5000, 135],[0, 165],[5000, 165]])
values = np.array([[300, 380, 300, 390, 300, 400]]).transpose()
xi = np.array([[2500, 105],[2500, 125],[2500, 135],[2500, 150],[2500, 165]])

gd = griddata(points, values, xi, method='linear', rescale=True, fill_value=np.nan)

# Replace NaN values with the mean of non-NaN values in the column
result = np.nanmean(gd, axis=1)

print(result)

This should give you the expected result:

[340.         343.33333333 345.         347.5        350.        ]

By setting fill_value=np.nan, you indicate that points outside the convex hull should be filled with NaN. Then, np.nanmean is used to compute the mean, excluding NaN values.

2023-11-23