Подтвердить что ты не робот

Интерполяция 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()
4b9b3361

Ответ 1

Похоже, ты понял.

В вашем примере с верхним кодом и в предыдущем (связанном) вопросе у вас есть структурированные данные. Который может быть интерполирован с помощью RectBivariateSpline или interp2d. Это означает, что у вас есть данные, которые можно описать на сетке (все точки в сетке имеют известное значение). Сетка не обязательно должна иметь все те же dx и dy. (если все dx и dy равны, у вас будет регулярная сетка)

Теперь ваш текущий вопрос спрашивает, что делать, если не все точки известны. Это называется неструктурированными данными. Все, что у вас есть, - это выбор точек в поле. Вы не можете построить прямоугольники, где все вершины имеют известные значения. Для этого типа данных вы можете использовать (как есть) griddata или аромат BivariateSpline.

Теперь, что выбрать?

Ближайшая аналогия со структурированным RectBivariateSpline является одним из неструктурированных BivariateSpline классов: SmoothBivariateSpline или LSQBivariateSpline. Если вы хотите использовать сплайны для интерполяции данных, перейдите к ним. это делает вашу функцию гладкой и дифференцируемой, но вы можете получить поверхность, которая качается вне Z.max() или Z.min().

Поскольку вы устанавливаете ky=1 и kx=1 и получаете то, что я уверен, это просто линейная интерполяция на структурированных данных, я бы просто переключился с на на interp2d схема интерполяции структурированной сетки. Я знаю, что в документации говорится, что для регулярных сеток, но пример в __doc__ сам по себе структурирован, а не является регулярным.

Мне было бы любопытно, если бы вы обнаружили какие-либо существенные различия между этими методами, если вы закончите переключение. Добро пожаловать в SciPy.