interp2d не обрабатывает предварительно неупорядоченные входы при использовании - PullRequest
0 голосов
/ 23 сентября 2019

Сегодня Python укусил меня, с поведением interp2d я не ожидал.Я привык к interp1d, например, определяя

f = interp1d(np.linspace(0, 1, 10), np.linspace(1, 2, 10), kind='linear')

, мы получаем интерполятор, чувствительный к порядку аргументов, с которыми он вызывается.f([0, 0.5, 1]) возвращает array([1, 1.5, 2]), а f([0.5, 1, 0]) возвращает array([1.5, 2], 1).Как я и ожидал.

Однако с interp2d я получаю что-то другое.После определения

g = interp2d([0,1], [0,1], [[1,2], [2,3]], kind='linear')

вызов g([0, 0.2, 1], [0.3]) возвращает array([1.3, 1.5, 2.3]), но переупорядочение аргумента не действует.Например, g([0.2, 1, 0]) дает мне то же самое.Что нежелательно.Я не нахожу никаких следов этого в документации interp2d, не говоря уже о возможности изменить это поведение.

Я также попытался преобразовать этот пример в RectBivariateSpline, вызов вызывает исключение, когда заданный векторне заказан: ValueError("Error code returnod by bispev: 10").

Я мог бы реализовать обертку вокруг interp2d с помощью argsort, чтобы он позаботился о порядке и впоследствии исправил его.Но мне трудно поверить, что это путь, предположив, что можно получить то, что я хочу, как данность.Предложения, пожалуйста!?

1 Ответ

1 голос
/ 23 сентября 2019

В функции вызова interp2d есть опция assume_sorted=False.Соответствующий код:

if not assume_sorted:
    x = np.sort(x)
    y = np.sort(y)

Так по умолчанию x и y и отсортированы перед использованием.Однако, в отличие от interp1d, «x и y должны быть массивами монотонно растущих значений», поэтому установка assume_sorted=True приводит к ValueError: Invalid input data.Нет выбора, кроме как выполнить интерполяцию, используя упорядоченные x и y.

RectBivariateSpline предоставляет выбор: «Оценивать ли результаты в сетке, охватываемой входными массивами, или в указанных точкахпо входным массивам. "

Например:

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]

Здесь выводятся не значения на двумерной сетке (массив 2d), а список значений (массив 1d).

...