Итак, я выполнял свое задание, и мы должны использовать для этого же интерполяцию (линейную интерполяцию). Нас попросили использовать пакет interp1d
из scipy.interpolate
и использовать его для генерации новых значений y
с учетом новых значений x
и старых координат (x1,y1)
и (x2,y2)
.
Чтобы получить новые координаты x
(давайте назовем это x_new
), я использовал np.linspace
между (x1,x2)
и новыми координатами y
(давайте назовем это y_new
). Я обнаружил, используя функцию interp1d
на x_new
.
Однако я также заметил, что применение np.linspace
на (y1,y2)
генерирует точно такие же значения y_new
, которые мы получили от interp1d
на x_new
.
Кто-нибудь может объяснить мне, почему это так? И если это правда, всегда ли это правда?
И если это всегда так, зачем нам вообще нужно использовать функцию interp1d
, если мы можем использовать np.linspace
вместо нее?
Вот код, который я написал:
import scipy.interpolate as ip
import numpy as np
x = [-1.5, 2.23]
y = [0.1, -11]
x_new = np.linspace(start=x[0], stop=x[-1], num=10)
print(x_new)
y_new = np.linspace(start=y[0], stop=y[-1], num=10)
print(y_new)
f = ip.interp1d(x, y)
y_new2 = f(x_new)
print(y_new2) # y_new2 values always the same as y_new
Причина, по которой вы наткнулись на это, заключается в том, что вы используете только две точки для интерполяции линейной функции. У вас есть в качестве входных данных два разных значения x
с соответствующими значениями y
. Затем вы просите interp1d
найти линейную функцию f(x)=m*x +b
, которая лучше всего соответствует вашим входным данным. Поскольку у вас есть только две точки в качестве входных данных, есть точное решение, потому что линейная функция точно определяется двумя точками. Чтобы в этом убедиться: возьмите лист бумаги, нарисуйте две точки и подумайте, сколько прямых линий вы можете нарисовать, чтобы соединить эти точки.
Линейная функция, которую вы получаете от двух входных точек, определяется параметрами m=(y1-y2)/(x1-x2)
и b=y1-m*x1
, где (x1,y1),(x2,y2)
- это ваши две входные точки (или элементы в ваших массивах x
и y
во фрагменте кода.
Итак, что теперь делает np.linspace(start, stop, num,...)
? Это дает вам num
, равномерно распределенные точки между start
и stop
. Это точки start
, start + delta
, ..., end
. Ширина шага delta
задается delta=(end-start)/(num - 1)
. Значение -1 связано с тем, что вы хотите включить свою конечную точку. Таким образом, точка n
в вашем интервале будет лежать в точке xn=x1+n*(x2-x1)/(num-1)
. При каких значениях y
эти точки окажутся после применения нашей линейной функции из interp1d
? Подключим:
f(xn)=m*xn+b=(y1-y2)/(x1-x2)*(x1+n/(num-1)*(x2-x1)) + y1-(y1-y1)/(x1-x2)*x1
. Упрощение этого приводит к f(xn)=(y2-y1)*n/(num - 1) + y1
. И это именно то, что вы получаете от np.linspace(y1,y2,num)
, т.е. f(xn)=yn
!
Так всегда ли это работает? Нет! Мы использовали тот факт, что наша линейная функция определяется двумя конечными точками интервалов, которые мы используем в np.linspace
. Так что в целом это не сработает. Попробуйте добавить еще одно значение x
и еще одно значение y
в свой список ввода, а затем сравните результаты.