В этом руководстве объясняется, как интерполировать Python Scipy одно-, двух-, трех- и многомерных данных с использованием различных методов, таких как interpn1d и т. д.
- Класс interp1d()
- Метод Griddata()
- Класс interp2d()
- Класс CubicSpline()
- Класс Rbf()
- Метод interpn()
- Класс NearestNDInterpolator()
Класс interp1d()
Python Scipy содержит класс interp1d() в модуле scipy.interpolate, который используется для интерполяции одномерных функций.
Синтаксис:
scipy.interpolate.interp1d(x, y, kind='linear', axis=- 1, copy=True, bounds_error=None, fill_value=nan, assume_sorted=False)
Где параметры:
- x(array_data): одномерный массив реальных значений.
- y(array_data): Массив ND с реальным значением. Необходимо, чтобы длина y по оси интерполяции совпадала с длиной x.
- kind(int, string): определяет тип интерполяции в виде строки или целого числа, а также порядок использования сплайн-интерполятора. Строка должна относиться к одной из следующих категорий: линейная, ближайшая, ближайшая, нулевая, линейная, квадратичная, кубическая, предыдущая или следующая. Термины «нулевой», «линейный», «квадратичный» и «кубический» обозначают сплайн-интерполяции нулевого, первого, второго или третьего порядка; «Предыдущий», «Следующий» и «Ближайший» просто возвращают предыдущее или следующее значение точки; «Ближайший вверх», который округляет в большую сторону, и «ближайший», который округляет в меньшую сторону, используются при интерполяции полуцелых чисел(например, 0,5, 1,5). Линейный — значение по умолчанию.
- axis(int): указывает ось Y, которая будет использоваться для интерполяции. Последняя ось y — это значение по умолчанию для интерполяции.
- copy(boolean): если True, x и y копируются внутри класса. Ссылки на x и y используются, если установлено значение False. Копирование — действие по умолчанию.
- bounds_error(boolean): если true, каждый раз, когда интерполяция выполняется для значения за пределами диапазона x, возникает ошибка ValueError(где необходима экстраполяция). Если значение равно False, значение заполнения присваивается значениям, выходящим за пределы. Ошибки возникают по умолчанию, если не указано значение fill value=»extrapolate».
- fill_value(array_data, extrapolate): если true, каждый раз, когда интерполяция выполняется для значения за пределами диапазона x, возникает ошибка ValueError(где необходима экстраполяция). Если значение равно False, значение заполнения присваивается значениям, выходящим за пределы. Ошибки возникают по умолчанию, если не указано значение fill value=»extrapolate».
- предполагается, что сортировка (логическое значение): если значение равно False, значения x сортируются первыми и могут быть в любом порядке. Если True, x должен быть массивом значений, которые монотонно увеличиваются.
Импортируйте необходимые библиотеки или методы, используя приведенный ниже код Python.
from scipy.interpolate import interp1d import matplotlib.pyplot as plt import numpy as np
Создайте данные x и y и передайте их методу interp1d(), чтобы вернуть функцию, используя приведенный ниже код.
x_ = np.arange(0, 15) y_ = np.exp(-x_/4.0) f_ = interp1d(x_, y_)
Постройте возвращенную выше функцию с новыми данными, используя приведенный ниже код.
xnew_ = np.arange(0, 14, 0.1) ynew_ = f_(xnew_) plt.plot(x_, y_, 'o', xnew_, ynew_, '-') plt.show()
Метод Griddata()
В Python Scipy есть метод Griddata() в модуле scipy.interpolate, который используется для интерполяции неструктурированных данных DD.
Синтаксис:
scipy.interpolate.griddata(points, values, xi, method='linear', fill_value=nan, rescale=False)
Где параметры:
- points: координаты точки данных.
- values: это значения данных.
- xi: Точки, где данные могут быть интерполированы.
- method: метод интерполяции, такой как кубическая, линейная, ближайшая.
- fill_value(float): значение, используемое в качестве замены для запрошенных точек, находящихся за пределами выпуклой оболочки входных точек. Если ничего не указано, по умолчанию используется nan. По отношению к «ближайшей» технике этот параметр не имеет никакого влияния.
- rescale (boolean): интерполяция выполняется после масштабирования точек до единичного куба. Это полезно, если какое-либо из входных измерений содержит единицы, которые несоизмеримы и различаются на большие порядки.
Метод Griddata() возвращает ndarray, который интерполировал массив значений.
Импортируйте необходимые библиотеки или методы, используя приведенный ниже код Python.
from scipy import interpolate import matplotlib.pyplot as plt import numpy as np
Подумайте об интерполяции 2D-функции, как показано ниже.
def fun(x_, y_): return x_*(1-x_)*np.cos(3*np.pi*x_) * np.sin(3*np.pi*y_**2)**2
На сетке [0, 1]x[0, 1].
grid_x_, grid_y_ = np.mgrid[0:1:100j, 0:1:200j]
Однако у нас есть только 1000 точек данных, значения которых мы знаем.
rng_ = np.random.default_rng() points_ = rng.random((1000, 2)) values_ = fun(points_[:,0], points_[:,1])
Для этого можно использовать Griddata, в разделе ниже мы тестируем каждый метод интерполяции.
grid_z0_ = interpolate.griddata(points_, values_,(grid_x_, grid_y_), method='nearest') grid_z1_ = interpolate.griddata(points_, values_,(grid_x_, grid_y_), method='linear') grid_z2_ = interpolate.griddata(points_, values_,(grid_x_, grid_y_), method='cubic')
Как можно видеть, все подходы в некоторой степени воссоздают точный результат, но для этой гладкой функции лучше всего подходит кусочно-кубический интерполянт.
plt.subplot(221) plt.imshow(fun(grid_x_, grid_y_).T, extent=(0,1,0,1), origin='lower') plt.plot(points_[:,0], points_[:,1], 'k.', ms=1) plt.title('Original') plt.subplot(222) plt.imshow(grid_z0_.T, extent=(0,1,0,1), origin='lower') plt.title('Nearest') plt.subplot(223) plt.imshow(grid_z1_.T, extent=(0,1,0,1), origin='lower') plt.title('Linear') plt.subplot(224) plt.imshow(grid_z2_.T, extent=(0,1,0,1), origin='lower') plt.title('Cubic') plt.gcf().set_size_inches(6, 6) plt.show()
Класс interp2d()
Python Scipy содержит класс interp2d() в модуле scipy.interpolate, который используется для двумерной сетки интерполяции.
scipy.interpolate.interp2d(x, y, z, kind='linear', copy=True, bounds_error=False, fill_value=None)[source]
Где параметры:
- x,y(array_data): координаты точек данных определяются с использованием массивов. Если точки находятся на регулярной сетке, x и y можно использовать для определения координат столбца и строки соответственно.
- z(array_data): значения интерполяции для функции в точках данных. Если z — многомерный массив, перед использованием используется «упорядочение Фортрана(order=’F’)», чтобы сгладить его. Если x и y определяют координаты столбца и строки, длина сплющенного массива z равна «len(x)*len(y)»; в противном случае это «len(z) == len(x) == len(y)».
- kind (квинтическая, линейная, кубическая): Соответствующий тип сплайн-интерполяции. Линейный — значение по умолчанию.
- copy (boolean): Если True, класс создает внутренние копии x, y и z. Ссылки можно использовать, если установлено значение False. Копирование — действие по умолчанию.
- Bounds_error(boolean): Если значение True, ValueError возникает всякий раз, когда запрашиваются интерполированные значения, выходящие за пределы диапазона входных данных(x, y). Значение заполнения используется, если установлено значение False.
- fill_value(число): значение, которое будет использоваться для точек за пределами области интерполяции, если указано. Значения за пределами домена экстраполируются с использованием экстраполяции ближайшего соседа, если они отсутствуют(Нет).
Импортируйте необходимые библиотеки или методы, используя приведенный ниже код.
from scipy.interpolate import interp2d import matplotlib.pyplot as plt import numpy as np
Создайте двумерную сетку и выполните на ней интерполяцию.
x_ = np.arange(-4.01, 4.01, 0.25) y_ = np.arange(-4.01, 4.01, 0.25) xx_, yy_ = np.meshgrid(x_, y_) z_ = np.sin(xx_**2+yy_**2) f_ = interp2d(x_, y_, z_, kind='cubic')
Постройте результат, используя функцию интерполяции, которую мы только что получили, используя приведенный ниже код.
xnew_ = np.arange(-4.01, 4.01, 1e-2) ynew_ = np.arange(-4.01, 4.01, 1e-2) znew_ = f_(xnew_, ynew_) plt.plot(x_, z_[0, :], 'ro-', xnew_, znew_[0, :], 'b-') plt.show()
Класс CubicSpline()
В Python Scipy есть класс CubicSpline() в модуле scipy, который интерполирует данные с использованием кубических сплайнов.
Используйте кусочный кубический полином, который дважды непрерывно дифференцируем, чтобы интерполировать данные. Результат отображается в виде экземпляра PPoly с точками останова, соответствующими предоставленным данным.
Синтаксис:
scipy.interpolate.CubicSpline(x, y, axis=0, bc_type='not-a-knot', extrapolate=None)
Где параметры:
- x(array_data): одномерный массив, хранящий значения независимой переменной. Требуются реальные, конечные и строго растущие значения.
- y(array_data): Массив, содержащий значения зависимой переменной. Независимо от того, сколько измерений он имеет, длина по оси(см. ниже) должна быть равна длине x. Ценности должны иметь конец.
- axis(int): ось, вдоль которой предположительно изменяется y. Другими словами, значения x[i] — это np.take(y, I axis=axis).
- bc_type(string, tuple): Тип граничного условия. Чтобы определить полиномиальные коэффициенты каждого сегмента, необходимы два дополнительных уравнения, которые предоставляются граничными условиями.
- extrapolate (периодическое, логическое значение): если bool решает, возвращать ли NaN или экстраполировать на точки выхода за пределы, используя первый и последний интервалы. Периодическая экстраполяция используется, если термин является «периодическим». Для экстраполяции установлено значение «периодический», если bc type=’ periodic’, если «Нет»(по умолчанию), и значение «Истина» в противном случае.
Импортируйте необходимые библиотеки или методы, используя приведенный ниже код.
from scipy.interpolate import CubicSpline import matplotlib.pyplot as plt import numpy as np
Давайте посмотрим, как дискретная синусоида интерполируется с использованием кубического сплайна, используя приведенный ниже код.
x_ = np.arange(10) y_ = np.sin(x_) cs_ = CubicSpline(x_, y_)
Постройте приведенные выше данные, используя новые данные.
xs_ = np.arange(-0.5, 9.6, 0.1) fig, ax = plt.subplots(figsize=(6.5, 4)) ax.plot(x_, y_, 'o', label='data') ax.plot(xs_, np.sin(xs_), label='true') ax.plot(xs_, cs_(xs_), label="S") ax.plot(xs_, cs_(xs_, 1), label="S'") ax.plot(xs_, cs_(xs_, 2), label="S''") ax.plot(xs_, cs_(xs_, 3), label="S'''") ax.set_xlim(-0.5, 9.5) ax.legend(loc='lower left', ncol=2) plt.show()
Класс Rbf()
В Python Scipy есть класс Rbf() в модуле scipy.interpolate для интерполяции функций из разбросанных данных ND в область MD с использованием радиальных базисных функций.
Синтаксис:
scipy.interpolate.Rbf(*args, **kwargs)
Где параметры:
- *args(array_data): координаты узлов — x, y, z,…, d, а массив значений в узлах — d.
- function(string): Радиальная базисная функция со значением по умолчанию «мультиквадрическая» основана на радиусе r, определяемом нормой(по умолчанию — евклидово расстояние).
- epsilon(float): функции Гаусса или мультиквадрики предоставляют регулируемую константу, которая по умолчанию равна приблизительному среднему расстоянию между узлами(что является хорошим началом).
- Smooth(float): значения выше нуля улучшают гладкость аппроксимации. Когда для интерполяции установлено значение 0, функция всегда проходит через узловые точки.
- standard (строка): функция, которая принимает массив позиций(x, y, z,…) в качестве входных данных и возвращает «расстояние» между двумя точками в виде массива расстояний. Например, настройка по умолчанию — «евклидова», которая создает матрицу расстояний, например, между каждой точкой в x1 и каждой точкой в x2. Документация «scipy.spatial.distances.cdist» содержит дополнительные параметры.
- mode(строка): Режим интерполяции может быть либо «1-D»(по умолчанию), либо «ND». Когда это «1-D», данные d обрабатываются как 1-D и внутренне сглаживаются. Данные d считаются массивом фигур(n образцов, m), если это «ND», где m — размер целевой области.
Импортируйте необходимые библиотеки или методы, используя приведенный ниже код Python.
from scipy import integrate import numpy as np
Создайте экземпляр интерполятора радиальной базисной функции, используя приведенный ниже код.
rng_ = np.random.default_rng() x_, y_, z_, d_ = rng_.random((4, 40)) rbfi_ = interpolate.Rbf(x_, y_, z_, d_)
Давайте посмотрим интерполированные значения, используя приведенный ниже код.
xi_ = yi_ = zi_ = np.linspace(0, 1, 20) di_ = rbfi_(xi_, yi_, zi_) di_.shape
Метод interpn()
В Python Scipy есть метод interpn() в модуле scipy.interpolate, который выполняет интерполяцию в нескольких измерениях на прямолинейных или регулярных сетках.
Эта функция поддерживает только прямолинейные сетки, которые представляют собой прямоугольные сетки с четным или нечетным интервалом, поэтому, строго говоря, поддерживаются не все регулярные сетки.
Синтаксис:
scipy.interpolate.interpn(points, values, xi, method='linear', bounds_error=True, fill_value=nan)
Где параметры:
- Points(ndarray float): n-мерная регулярная сетка определяется точками. Точки каждого измерения должны обязательно возрастать или опускаться.
- values(array_data): данные в n измерениях в обычной сетке. Возможен прием сложных данных.
- xi(ndim): расположение точек выборки для данных с координатной сеткой.
- метод(строка): используемый метод интерполяции. Поддерживаются термины «линейный», «ближайший» и «splinef2d». Для «splinef2d» принимаются только двумерные данные.
- Bounds_error(boolean): Если значение True, ValueError возникает всякий раз, когда запрашиваются интерполированные значения, выходящие за пределы диапазона входных данных(x, y). Значение заполнения используется, если установлено значение False.
- fill_value(число): значение, которое будет использоваться для точек за пределами области интерполяции, если указано. Значения за пределами домена экстраполируются с использованием экстраполяции ближайшего соседа, если они отсутствуют(Нет).
Метод interpn() возвращает values_x (значения, интерполированные во входных местоположениях) типа ndarray.
Давайте возьмем пример и применим простую примерную функцию к точкам стандартной трехмерной сетки.
Импортируйте необходимые библиотеки или методы, используя приведенный ниже код Python.
from scipy import interpolate import numpy as np
def val_fun_3d(x_, y_, z_): return 2 * x_ + 2 * y_ - z_ x_ = np.linspace(0, 3, 4) y_ = np.linspace(0, 4, 5) z_ = np.linspace(0, 5, 6) points_ =(x_, y_, z_) values_ = val_fun_3d(*np.meshgrid(*points_, indexing='ij'))
В определенном месте оцените интерполирующую функцию, используя приведенный ниже код.
point_ = np.array([2.20, 3.10, 1.12]) print(interpolate.interpn(points_, values_, point_))
Класс NearestNDInterpolator()
Класс NearestNDInterpolator() модуля scipy.interpolate в Python Scipy, который используется для интерполяции ближайшего соседа в измерениях N > 1.
Синтаксис:
scipy.interpolate.NearestNDInterpolator(x, y, rescale=False, tree_options=None)
Где параметры:
- x(Npoints, Ndims): координаты точки данных.
- y(Npoints): это значения данных.
- rescale(boolean): перед применением интерполяции измените масштаб точек до единичного куба. Это полезно, если некоторые из входных измерений имеют несоизмеримые единицы измерения или отклоняются на большие порядки.
- Tree_options: параметры, предоставленные cKDTree.
Импортируйте необходимые библиотеки или методы, используя приведенный ниже код.
from scipy.interpolate import interp2d import matplotlib.pyplot as plt import numpy as np
Создайте сетку, используя приведенный ниже код.
rng = np.random.default_rng() x_ = rng.random(10) - 0.5 y_ = rng.random(10) - 0.5 z_ = np.hypot(x_, y_) X_ = np.linspace(min(x_), max(x_)) Y_ = np.linspace(min(y_), max(y_)) X_, Y_ = np.meshgrid(X_, Y_)
Теперь используйте приведенную выше 2D-сетку для интерполяции, используя приведенный ниже код.
interp_ = interpolate.NearestNDInterpolator(list(zip(x_, y_)), z_) Z_ = interp_(X_, Y_) plt.pcolormesh(X_, Y_, Z_, shading='auto') plt.plot(x_, y_, "ok", label="input point") plt.legend() plt.colorbar() plt.axis("equal") plt.show()