Reputation: 890
Today Python bit me, with a behavior of interp2d
I did not expect. I am used to interp1d
, for instance, defining
f = interp1d(np.linspace(0, 1, 10), np.linspace(1, 2, 10), kind='linear')
we get an interpolator that is sensitive to the order of the arguments its called with. f([0, 0.5, 1])
returns array([1, 1.5, 2])
while f([0.5, 1, 0])
returns array([1.5, 2], 1)
. As I would expect.
However, with interp2d
I'm getting something different. After defining
g = interp2d([0,1], [0,1], [[1,2], [2,3]], kind='linear')
the call g([0, 0.2, 1], [0.3])
returns array([1.3, 1.5, 2.3])
, but reordering the argument takes no effect. For instance, g([0.2, 1, 0])
gives me exactly the same. Which is undesired. I find no traces of this in interp2d
's documentation, let alone an option to change this behavior.
I also tried and converted this example to RectBivariateSpline
, the invocation raises an exception when the vector given is not ordered: ValueError("Error code returnod by bispev: 10")
.
I could implement a wrapper around interp2d with argsort
, so that it takes care of the order and corrects it afterwards. But I find hard to believe this is the way to go, would assume it is possible to get what I want as a given. Suggestions, please!?
Upvotes: 2
Views: 523
Reputation: 4151
There is an option assume_sorted=False
in the interp2d's call function. The corresponding code is:
if not assume_sorted:
x = np.sort(x)
y = np.sort(y)
So by default x and y and sorted before use. However, unlike interp1d
, "x and y have to be arrays of monotonically increasing values.", thus setting assume_sorted=True
leads to ValueError: Invalid input data
. There is no choice but to perform the interpolation using ordered x and y.
RectBivariateSpline provides the choice "Whether to evaluate the results on a grid spanned by the input arrays, or at points specified by the input arrays."
For instance:
from scipy.interpolate import RectBivariateSpline
g = RectBivariateSpline([0, 1, 2], [0, 1],
np.array([[0, 1, 2], [0, 1, 2]]).T,
kx=1, ky=1) # x, and y are reversed compared to interp2d
x = [0.3, 0.2, 0.1]
y = [0.2, ]
print(g(x, y)) # -> ValueError: Error code returned by bispev: 10
x = [0.3, 0.2, 0.1]
y = [0.2,]*len(x)
print(g(x, y, grid=False)) # -> [0.3 0.2 0.1]
Here the output is no more values on a 2D grid (2d array) but a list of values (1d array).
Upvotes: 3