Как сделать 2D-интерполяцию в таблице в Python? - PullRequest
0 голосов
/ 28 мая 2020

У меня есть таблица чисел с двумя начальными строками и столбцами (выделенными жирным шрифтом), которые являются входными значениями CI и CII. мой ввод может быть значением между этими двумя значениями, и на основе этого я должен интерполировать значения таблицы, пересекая их.

так, скажем, я должен найти соответствующее значение из таблицы для CI = 0,33, который находится между 0,3 и 0,35 в первой строке, выделенной жирным шрифтом, и CII = 1,1.

Другие вопросы по 2D-интерполяции мне не очень помогли. Потому что я использую python add в другом программном обеспечении, где я не могу импортировать scipty.interp2D. Я был бы очень благодарен, если бы какое-то решение было предложено без необходимости указывать c библиотека

values

Я не уверен, какой тип интерполяции использовать. возможно линейный. Чтобы дать лучшую перспективу, я построил 3 произвольные строки из таблицы, просто взяв строку и построив ее против номера образца, кажется, что они имеют разное поведение по образцам. первые увеличиваются, последние убывают, но никогда не являются строкой:

enter image description here

1 Ответ

1 голос
/ 28 мая 2020

Какую интерполяцию вы хотите? Полиномиальный? Экспоненциально кусочно гладко? Можно ли пошагово линейно?

Предполагая пошаговую линейную, вы можете просто написать функцию вручную:

# Sample data. 
X    = [0,5,10] # Left to right, like in your table. 
Y    = [0,2]    # Top to bottom, like in your table. 
grid = [[1,2,4],[4,5,10]]

def f(x,y):
    # Find the vales that x and y are between. 
    xi,yi = None,None
    for i,(x1,x2) in enumerate(zip(X[:-1],X[1:])):
        if x1 <= x <= x2:
            xi,w_x2,w_x1 = i,(x-x1)/(x2-x1),(x2-x)/(x2-x1)
            break
    for i,(y1,y2) in enumerate(zip(Y[:-1],Y[1:])):
        if y1 <= y <= y2:
            yi,w_y2,w_y1 = i,(y-y1)/(y2-y1),(y2-y)/(y2-y1)
            break
    if xi is None or yi is None:
        return False 
        # You could add special cases to interpolate past the range if you would like. 
    # Find the weighted average between the four corners. 
    ave  = grid[yi][xi]    *w_y1*w_x1
    ave += grid[yi][xi+1]  *w_y1*w_x2
    ave += grid[yi+1][xi]  *w_y2*w_x1
    ave += grid[yi+1][xi+1]*w_y2*w_x2
    return ave

print(f(0,0),f(2.5,0),f(4,0),f(5,0),f(7.5,0),f(10,0))
print(f(0,1),f(2.5,1),f(4,1),f(5,1),f(7.5,1),f(10,1))
print(f(0,2),f(2.5,2),f(4,2),f(5,2),f(7.5,2),f(10,2))

Это можно было бы сделать более эффективно с дополнительной информацией. Например, если у вас есть согласованная x_delta между вашими значениями x, вы можете пропустить циклы for. Вы также можете пропустить циклы for, если используете SortedList из пакета sortedcontainers. Вероятно, это также можно было бы адаптировать для numpy, если бы вы хотели использовать массивы вместо списков, et c.

Вы не предоставили мне никакого рабочего кода или знаний о модулях, которые вы можете использовать, или алгоритме, который вам нужен, поэтому я написал это как можно лучше. : -)


Изменить:

Вы не должны заставлять людей вводить ваши данные из изображения PNG. Вот небольшой раздел, больше не могу напечатать.

X    = [0,0.05,0.1,0.15,0.2] 
Y    = [0.2,0.4] 
grid = [[1,1.116,1.211,1.297,1.376],[1,1.094,1.174,1.248,1.319]]

...

print(f(0,0.2),f(0.025,0.2),f(0.05,0.2))
...