Интерполяция Python/Scipy 2D (неравномерные данные)
Это следующий вопрос к моему предыдущему сообщению: Python/Scipy Interpolation (map_coordinates)
Скажем, я хочу интерполировать по 2d прямоугольной области. Моя переменная "z" содержит данные, как показано ниже. Каждый столбец имеет постоянное значение, однако каждая строка массива может иметь другое значение, как показано в комментарии ниже.
from scipy import interpolate
from numpy import array
import numpy as np
# # 0.0000, 0.1750, 0.8170, 1.0000
z = array([[-2.2818,-2.2818,-0.9309,-0.9309], # 0.0000, 0.0000, 0.0000, 0.0000
[-2.2818,-2.2818,-0.9309,-0.9309], # 0.2620, 0.2784, 0.3379, 0.3526
[-1.4891,-1.4891,-0.5531,-0.5531], # 0.6121, 0.6351, 0.7118, 0.7309
[-1.4891,-1.4891,-0.5531,-0.5531]]) # 1.0000, 1.0000, 1.0000, 1.0000
# Rows, Columns = z.shape
cols = array([0.0000, 0.1750, 0.8170, 1.0000])
rows = array([0.0000, 0.2620, 0.6121, 1.0000])
sp = interpolate.RectBivariateSpline(rows, cols, z, kx=1, ky=1, s=0)
xi = np.array([0.00000, 0.26200, 0.27840, 0.33790, 0.35260, 0.61210, 0.63510,
0.71180, 0.73090, 1.00000], dtype=np.float)
yi = np.array([0.000, 0.167, 0.815, 1.000], dtype=np.float)
print sp(xi, yi)
В качестве другого способа визуализации этого массива значений я KNOW будет:
rows = array([0.0000, 0.2620, 0.2784, 0.3379, 0.3526,
0.6121, 0.6351, 0.7118, 0.7309, 1.0000])
# # 0.0000, 0.1750, 0.8170, 1.0000
z = array([[-2.2818,-2.2818,-0.9309,-0.9309], # 0.0000
[-2.2818, ?, ?, ?], # 0.2620,
[ ?,-2.2818, ?, ?], # 0.2784
[ ?, ?,-0.9309, ?], # 0.3379
[ ? ,?, ?,-0.9309], # 0.3526
[-1.4891, ?, ?, ?], # 0.6121
[ ?,-1.4891, ?, ?], # 0.6351
[ ?, ?,-0.5531, ?], # 0.7118
[ ?, ?, ?,-0.5531], # 0.7309
[-1.4891,-1.4891,-0.5531,-0.5531]]) # 1.0000
Я не знаю, что? значения, и они должны быть интерполированы. Я попытался заменить их на None, но затем получить "nan" для всех моих результатов.
EDIT:
Я думаю, мне нужно использовать либо "griddata", либо "interp2". Кажется, что griddata дает результат, которого я ожидаю, но "interp2" не делает.
from scipy import interpolate
from numpy import array
import numpy as np
z = array([[-2.2818,-2.2818,-0.9309,-0.9309],
[-2.2818,-2.2818,-0.9309,-0.9309],
[-1.4891,-1.4891,-0.5531,-0.5531],
[-1.4891,-1.4891,-0.5531,-0.5531]])
rows = array([0.0000, 0.0000, 0.0000, 0.0000,
0.2620, 0.2784, 0.3379, 0.3526,
0.6121, 0.6351, 0.7118, 0.7309,
1.0000, 1.0000, 1.0000, 1.0000])
cols = array([0.0000, 0.1750, 0.8180, 1.0000,
0.0000, 0.1750, 0.8180, 1.0000,
0.0000, 0.1750, 0.8180, 1.0000,
0.0000, 0.1750, 0.8180, 1.0000])
xi = array([0.0000, 0.2620, 0.2784, 0.3379, 0.3526, 0.6121, 0.6351, 0.7118,
0.7309, 1.0000], dtype=np.float)
yi = array([0.000, 0.175, 0.818, 1.000], dtype=np.float)
GD = interpolate.griddata((rows, cols), z.ravel(),
(xi[None,:], yi[:,None]), method='linear')
I2 = interpolate.interp2d(rows, cols, z, kind='linear')
print GD.reshape(4, 10).T
print '\n'
print I2(xi, yi).reshape(4, 10).T
import matplotlib.pyplot as plt
import numpy.ma as ma
plt.figure()
GD = interpolate.griddata((rows.ravel(), cols.ravel()), z.ravel(),
(xi[None,:], yi[:,None]), method='linear')
CS = plt.contour(xi,yi,GD,15,linewidths=0.5,colors='k')
CS = plt.contourf(xi,yi,GD,15,cmap=plt.cm.jet)
plt.colorbar()
plt.scatter(rows,cols,marker='o',c='b',s=5)
plt.figure()
I2 = I2(xi, yi)
CS = plt.contour(xi,yi,I2,15,linewidths=0.5,colors='k')
CS = plt.contourf(xi,yi,I2,15,cmap=plt.cm.jet)
plt.colorbar()
plt.scatter(rows,cols,marker='o',c='b',s=5)
plt.show()
Ответы
Ответ 1
Похоже, ты понял.
В вашем примере с верхним кодом и в предыдущем (связанном) вопросе у вас есть структурированные данные. Который может быть интерполирован с помощью RectBivariateSpline
или interp2d
. Это означает, что у вас есть данные, которые можно описать на сетке (все точки в сетке имеют известное значение). Сетка не обязательно должна иметь все те же dx и dy. (если все dx и dy равны, у вас будет регулярная сетка)
Теперь ваш текущий вопрос спрашивает, что делать, если не все точки известны. Это называется неструктурированными данными. Все, что у вас есть, - это выбор точек в поле. Вы не можете построить прямоугольники, где все вершины имеют известные значения. Для этого типа данных вы можете использовать (как есть) griddata
или аромат BivariateSpline
.
Теперь, что выбрать?
Ближайшая аналогия со структурированным RectBivariateSpline
является одним из неструктурированных BivariateSpline
классов: SmoothBivariateSpline
или LSQBivariateSpline
. Если вы хотите использовать сплайны для интерполяции данных, перейдите к ним. это делает вашу функцию гладкой и дифференцируемой, но вы можете получить поверхность, которая качается вне Z.max() или Z.min().
Поскольку вы устанавливаете ky=1
и kx=1
и получаете то, что я уверен, это просто линейная интерполяция на структурированных данных, я бы просто переключился с на на interp2d
схема интерполяции структурированной сетки. Я знаю, что в документации говорится, что для регулярных сеток, но пример в __doc__
сам по себе структурирован, а не является регулярным.
Мне было бы любопытно, если бы вы обнаружили какие-либо существенные различия между этими методами, если вы закончите переключение. Добро пожаловать в SciPy.