#python #numpy #interpolation
#python #numpy #интерполяция
Вопрос:
Я хочу выполнить интерполяцию обратного типа (numpy).
Рассмотрим случай, когда у меня есть значение «риска», равное 2,2, и оно сопоставляется с этим значением тенора, равным 1,50. Рассмотрим, есть ли тенор-список списка (или массива) = [0.5, 1.0, 2.0, 3.0, 5.0]. Теперь я хотел бы приписать это значение риска 2.2 тому, каким оно было бы, сопоставленное с ближайшими двумя точками привязки (в данном случае 1.0 и 2.0), в форме линейной интерполяции.
В этом примере функция сгенерирует значение риска 2.0 (которое сопоставляется со значением истечения срока действия 1.50) для
- для точки привязки 1.0: из 2.2 * (1.5 — 1.0)/(2.0 — 1.0)
- для точки привязки 2.0: из 2.2 * (2.0 — 1.5)/(2.0 — 1.0)
Есть ли код numpy / scipy / panda или python, который мог бы это сделать?
Спасибо!
Комментарии:
1. Для меня это не выглядит линейным. В основном значения в
1.0
и2.0
1.5
— это значение, разделенное на2
.2. привет @QuangHoang, это самый простой пример, о котором я мог подумать … реальность была бы чем-то вроде заданного (a) массива значений риска [0.422, 1.053, 100.423, -99.53], и (b) сопоставлены с тенором-массивом [1.0, 2.0, 5.0, 10.0], какможно ли присвоить массив значений риска большему тенору-массиву [1.0, 2.0, 3.0, 5.0, 7.0, 10.0, 12.0, 15.0] где исходные значения риска перераспределяются в менее детализированную сетку с использованием линейной интерполяции
Ответ №1:
Ну, я попробовал немного другой подход, но, возможно, это вам поможет. Я пытаюсь интерполировать точки для новых точек сетки, используя interpolate.interp1d
(с возможностью экстраполяции точек fill_value="extrapolate"
), чтобы расширить диапазон за пределы заданного интервала. В вашем первом примере новые точки всегда были внутренними, в примере с комментариями также внешними, поэтому я использовал более общий случай. Это все еще может быть отшлифовано, но должно дать представление:
import numpy as np
from scipy import interpolate
def dist_val(vpt, arr):
dist = np.abs(arr-np.full_like(arr, vpt))
i0 = np.argmin(dist)
dist[i0] = np.max(dist) 1
i1 = np.argmin(dist)
return (i0, i1)
def dstr_lin(ra, tnl, tnh):
'''returns a risk-array like ra for tnh based on tnl'''
if len(tnh) < len(tnl) or len(ra) != len(tnl):
return -1
rah = []
for vh in tnh:
try:
rah.append((vh, ra[tnl.index(vh)]))
except ValueError:
rah.append((vh, float(interpolate.interp1d(tnl, ra, fill_value="extrapolate")(vh))))
return rah
ra = [0.422, 1.053, 100.423, -99.53]
tn_low = [1.0, 2.0, 5.0, 10.0]
tn_high = [1.0, 2.0, 3.0, 5.0, 7.0, 10.0, 12.0, 15.0]
print(dstr_lin(ra, tn_low, tn_high))
это приводит к
[(1.0, 0.422), (2.0, 1.053), (3.0, 34.17633333333333), (5.0, 100.423), (7.0, 20.4418), (10.0, -99.53), (12.0, -179.51120000000003), (15.0, -299.483)]
Осторожно, я не уверен, насколько «хорошо себя ведут» ваши данные, интерполяция или экстраполяция могут выходить за пределы диапазона, поэтому используйте с осторожностью.