Сохранение данных перед передачей в процедуру интерполяции - PullRequest
1 голос
/ 03 апреля 2019

Я начну с извинений, потому что я совершенно новичок в python (парень из Фортрана) и учусь на лету.В результате, вероятно, в моих знаниях есть некоторые довольно явные дыры, которые могут стать очевидными после прочтения моей текущей дилеммы.

У меня есть некоторые данные, которые необходимо записать в файл, где они затем могут быть прочитаны с помощью алгоритма интерполяции.На данный момент этот алгоритм интерполяции, вероятно, будет RectBivariateSpline от SciPi.Хотя интервалы X и Y не совпадают, они являются регулярными, поэтому это может показаться идеальным.

Данные обычно имеют вид

X1, Y1, F (X1, Y1)

X1, Y2, F (X1, Y2)

X1, Y3, F (X1, Y3)

X2, Y1, F (X2,Y1)

X2, Y2, F (X2, Y2)

X2, Y3, F (X2, Y3)

и т. Д. *

В этом случае F (X, Y) не является явной математической функцией, а скорее точкой данных для физической величины в точке X, Y.

Данные считываются из источника данных, который я в принципе могуУправляйте, используя

 data_array = np.loadtxt(Path/DataFile, dtype = Float, delimiter = ";", usecols = #) 

В этом случае, возможно, существует несколько разных столбцов с разными данными, но все они зависят от X и Y. Существует отдельный файл, который содержит информацию о диапазоне иразмер шага значений X и Y, которые я прочитал и сохранил в массиве.По крайней мере, я вполне уверен, что это массив, а не список, так как я где-то читал, что np.loadtxt и np.genfromtxt оба генерируют массивы numpy, а не списки vanilla python.

Я поиграл с различными идеями о том, как оптимально сохранить эти данные для передачи на другую машину, используя простую процедуру интерполяции, но я мог бы воспользоваться некоторыми советами.Сначала мне пришло в голову использовать

ArrayExample = np.Empty(xRange,yRange) 
For n in (xRange) 
    For m in (yRange) 
        ArrayExample[n,m] = F(X,Y)

Однако это ничего не делает для сохранения фактического количества X или Y, связанного со значением в массиве, и это необходимо для интерполяции, и это определенно необходимо для построения графика.,

Итак, мне пришло в голову, что, поскольку у меня есть значения X и Y в форме, из которой я могу довольно легко прочитать, я мог сделать что-то следующим образом.Где xvalues ​​и yvalues ​​- это массивы, в которых хранятся фактические значения X и Y.

ArrayExample = np.Empty(xRange,yRange,1) 
For n in (xRange) 
    For m in (yRange) 
        ArrayExample[n,m,1] = (xvalues[n],yvalues[m],F(X,Y))

После этого мне приходит в голову сохранить ArrayExample в качестве файла выбора, который будет перемещен куда угодно, а затем введен с помощью pickle надругой конец.

Однако, как только он у меня есть, я действительно не знаю, как заставить RectBivariateSpline принимать данные.Я попытался прочитать документацию на сайте scipy и поискать в Google, но все, что я нашел до сих пор, довольно бесполезно.Если у кого-то есть хорошие примеры того, как его можно использовать, это было бы очень полезно.

Буду признателен за любые советы, мысли или критику.

Спасибо!

1 Ответ

0 голосов
/ 03 апреля 2019

Я видел это раньше и надеялся, что кто-то, кто знает больше, чем я, ответил.Надеемся, что это может указать вам правильное направление

Чтобы использовать класс RectBivariateSpline, вам нужны x и y как 1d-массивы со значениями z как 2d-массив (len (x), len (y))

Numpy требует, чтобы любые конкретные индексы массива были целыми числами, а не числами с плавающей точкой.Координаты x и y необходимо преобразовать в целочисленные индексы, чтобы поместить данные z в массив.

import numpy as np
from scipy import interpolate

# Generate x and y arrays
x = np.linspace(45., 70., 70)
y = np.linspace(125/7, 59.876, 29)

# I don't know what your data looks like. Generate a list of dictionary records
data = []

for _x in x:
    for _y in y:
        data.append({'x': _x, 'y': _y, 'z': _x * _x - _y*_y/_x})

data[:100:10]
Out[4]: 
[{'x': 45.0, 'y': 17.857142857142858, 'z': 2017.9138321995465},
 {'x': 45.0, 'y': 32.86387755102041, 'z': 2000.9992344958118},
 {'x': 45.0, 'y': 47.870612244897956, 'z': 1974.075655184414},
 {'x': 45.36231884057971, 'y': 19.357816326530614, 'z': 2049.4792585649284},
 {'x': 45.36231884057971, 'y': 34.364551020408165, 'z': 2031.7068577153198},
 {'x': 45.36231884057971, 'y': 49.37128571428571, 'z': 2004.0054192006007},
 {'x': 45.72463768115942, 'y': 20.858489795918366, 'z': 2081.227345221296},
 {'x': 45.72463768115942, 'y': 35.86522448979592, 'z': 2062.610735570439},
 {'x': 45.72463768115942, 'y': 50.87195918367347, 'z': 2034.1437652565721},
 {'x': 46.08695652173913, 'y': 22.359163265306123, 'z': 2113.159976357177}]

def indexer(v):
    """ Returns a function to index into the array v by value.
        int( result + 0.5 ) to avoid any not quite equal with floats.
    """
    v_lo = v.min()
    v_range = v.max()-v_lo
    n = len(v)-1

    def func( x ):
        """ Returns an index from x. """
        return int(n*(x-v_lo)/v_range+0.5)
    return func

x_index = indexer(x)  # Function to index into the x values 
y_index = indexer(y)  # Function to index into the y values

z = np.empty((len(x), len(y)))

for rec in data:
    ix_x = x_index(rec['x'])  # Map the x value to an index
    ix_y = y_index(rec['y'])  # Map the y value to an index
    z[ix_x, ix_y] = rec['z']  # Place the z value at ix_x, ix_y

inter = interpolate.RectBivariateSpline( x, y, z)

inter(45.3, 18)  # Out[6]: array([[2044.93768211]])

inter(np.arange(45., 70.), 18)
Out[7]: 
   array([[2017.8       ], [2108.95652174], [2202.10638298], [2297.25      ],
          [2394.3877551 ], [2493.52      ], [2594.64705882], [2697.76923077],
          [2802.88679245], [2910.        ], [3019.10909091], [3130.21428571],
          [3243.31578947], [3358.4137931 ], [3475.50847458], [3594.6       ],
          [3715.68852459], [3838.77419355], [3963.85714286], [4090.9375    ],
          [4220.01538462], [4351.09090909], [4484.1641791 ], [4619.23529412],
          [4756.30434783]])

Надеемся, что, по крайней мере, некоторые указатели / идеи.

...