在将数据传递到插值例程之前进行存储

时间:2019-04-02 21:28:44

标签: python numpy scipy interpolation

我将首先道歉,因为我是python的新手(这里是Fortran的家伙),并且一直在学习。结果,我的知识可能存在一些明显的漏洞,这些漏洞在阅读我当前的困境后可能会很明显。

我有一些数据需要写入文件,然后可以通过插值算法读取该文件。目前,该插值算法可能将来自SciPi的RectBivariateSpline。虽然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数组,而不是普通的python列表。

关于如何最佳地存储要使用简单插值例程传输到另一台机器的数据的方法,我有很多想法,但是我可以使用一些建议。我第一次想到要使用

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

但是,这并不能保留与数组中的值关联的实际数量X或Y,这些对于插值是必不可少的,并且对于绘图绝对是必需的。

于是我想到,由于我已经很容易地读取了X和Y的值,因此我可以做以下事情。其中xvalue和yvalue是包含实际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网站上的文档并进行谷歌搜索,但是到目前为止,我发现的所有内容都无济于事。如果有人在如何使用它方面有很好的例子,那将非常有帮助。

您可能会提出的任何建议,想法或批评。

谢谢!

1 个答案:

答案 0 :(得分:0)

我较早地看到了这一点,并希望知道比我更多的人回答。 希望这可以为您指明正确的方向

要使用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]])

希望至少有一些指针/想法。