python - 如何在 NumPy 中构建三线性插值的查找表?

标签 python numpy interpolation lookup linear-interpolation

以下摘录是我试图为其构建 numpy 查找函数的 500 行表的摘录。我的问题是这些值是非线性的。

用户输入密度体积内容。所以函数将是:

defcapacity_lookup(密度、体积、含量:

例如,典型的用户条目为 capacity_lookup (47, 775, 41.3)。该函数应在值 45 和 50、密度 700 和 800 以及内容 40 和 45 之间进行插值。

表格摘录为:

Volume  Density        Content 
                <30 35  40  45  50>=
45.0    <=100   0.1 1.8 0.9 2.0 0.3
45.0    200     1.5 1.6 1.4 2.4 3.0
45.0    400     0.4 2.1 0.9 1.8 2.5
45.0    600     1.3 0.8 0.2 1.7 1.9
45.0    800     0.6 0.9 0.8 0.4 0.2
45.0    1000    0.3 0.8 0.5 0.3 1.0
45.0    1200    0.6 0.0 0.6 0.2 0.2
45.0    1400    0.6 0.4 0.3 0.7 0.1
45.0    >=1600  0.3 0.0 0.6 0.1 0.3
50.0    <=100   0.1 0.0 0.5 0.9 0.2
50.0    200     1.3 0.4 0.8 0.2 2.7
50.0    400     0.4 0.1 0.7 1.3 1.7
50.0    600     0.8 0.7 0.1 1.2 1.6
50.0    800     0.5 0.3 0.4 0.2 0.0
50.0    1000    0.2 0.4 0.4 0.2 0.3
50.0    1200    0.4 0.0 0.0 0.2 0.0
50.0    1400    0.0 0.3 0.1 0.5 0.1
50.0    >=1600  0.1 0.0 0.0 0.0 0.2
55.0    <=100   0.0 0.0 0.4 0.6 0.1
55.0    200     0.8 0.3 0.7 0.1 1.2
55.0    400     0.3 0.1 0.3 1.1 0.7
55.0    600     0.4 0.3 0.0 0.6 0.1
55.0    800     0.0 0.0 0.0 0.2 0.0
55.0    1000    0.2 0.1 0.2 0.1 0.3
55.0    1200    0.1 0.0 0.0 0.1 0.0
55.0    1400    0.0 0.2 0.0 0.2 0.1
55.0    >=1600  0.0 0.0 0.0 0.0 0.1

问题

如何存储 500 行表,以便可以对其非线性数据进行插值并根据用户输入获取正确的值?

澄清

  1. 如果用户输入以下向量 (775, 47, 41.3),程序应返回以下四个向量之间的插值:45.0, 600, 0.2, 1.7, 45.0 、800、0.8、0.450.0、600、0.1、1.250.0、800、0.4、0.2
  2. 假设数据将从数据库中提取为您设计的 numpy 数组

最佳答案

我发现的第一个困难是 <=>= ,我可以处理 Density 的四肢复制,并将其值更改为非常接近的虚拟值 991601 ,这不会影响插值。

Volume  Density        Content 
                <30 35  40  45  50>=
45.0     99   0.1 1.8 0.9 2.0 0.3
45.0    100   0.1 1.8 0.9 2.0 0.3
45.0    200     1.5 1.6 1.4 2.4 3.0
45.0    400     0.4 2.1 0.9 1.8 2.5
45.0    600     1.3 0.8 0.2 1.7 1.9
45.0    800     0.6 0.9 0.8 0.4 0.2
45.0    1000    0.3 0.8 0.5 0.3 1.0
45.0    1200    0.6 0.0 0.6 0.2 0.2
45.0    1400    0.6 0.4 0.3 0.7 0.1
45.0    1600  0.3 0.0 0.6 0.1 0.3
45.0    1601  0.3 0.0 0.6 0.1 0.3
50.0     99   0.1 0.0 0.5 0.9 0.2
50.0    100   0.1 0.0 0.5 0.9 0.2
50.0    200     1.3 0.4 0.8 0.2 2.7
50.0    400     0.4 0.1 0.7 1.3 1.7
50.0    600     0.8 0.7 0.1 1.2 1.6
50.0    800     0.5 0.3 0.4 0.2 0.0
50.0    1000    0.2 0.4 0.4 0.2 0.3
50.0    1200    0.4 0.0 0.0 0.2 0.0
50.0    1400    0.0 0.3 0.1 0.5 0.1
50.0    1600  0.1 0.0 0.0 0.0 0.2
50.0    1601  0.1 0.0 0.0 0.0 0.2
55.0     99   0.0 0.0 0.4 0.6 0.1
55.0    100   0.0 0.0 0.4 0.6 0.1
55.0    200     0.8 0.3 0.7 0.1 1.2
55.0    400     0.3 0.1 0.3 1.1 0.7
55.0    600     0.4 0.3 0.0 0.6 0.1
55.0    800     0.0 0.0 0.0 0.2 0.0
55.0    1000    0.2 0.1 0.2 0.1 0.3
55.0    1200    0.1 0.0 0.0 0.1 0.0
55.0    1400    0.0 0.2 0.0 0.2 0.1
55.0    1600  0.0 0.0 0.0 0.0 0.1
55.0    1601  0.0 0.0 0.0 0.0 0.1

然后,正如 @Jaime 已经指出的那样,您必须找到 8 个顶点才能进行三线性插值。

以下算法将为您提供分数:

import numpy as np
def get_8_points(filename, vi, di, ci):
    a = np.loadtxt(filename, skiprows=2)
    vol = a[:,0].repeat(a.shape[1]-2).reshape(-1,)
    den = a[:,1].repeat(a.shape[1]-2).reshape(-1,)
    #FIXME maybe you have to change the next line
    con = np.tile(np.array([30., 35., 40., 45., 50.]),a.shape[0]).reshape(-1,)
    #
    val = a[:,2:].reshape(a.shape[0]*5).reshape(-1,)

    u = np.unique(vol)
    diff = np.absolute(u-vi)
    vols = u[diff.argsort()][:2]

    u = np.unique(den)
    diff = np.absolute(u-di)
    dens = u[diff.argsort()][:2]

    u = np.unique(con)
    diff = np.absolute(u-ci)
    cons = u[diff.argsort()][:2]

    check = np.in1d(vol,vols) & np.in1d(den,dens) & np.in1d(con,cons)

    points = np.vstack((vol[check], den[check], con[check], val[check]))

    return points.T

使用您的示例:

vi, di, ci = 47, 775, 41.3
points = get_8_points(filename, vi, di, ci)
#array([[  4.50e+01,   6.00e+02,   4.00e+01,   2.00e-01],
#       [  4.50e+01,   6.00e+02,   4.50e+01,   1.70e+00],
#       [  4.50e+01,   8.00e+02,   4.00e+01,   8.00e-01],
#       [  4.50e+01,   8.00e+02,   4.50e+01,   4.00e-01],
#       [  5.00e+01,   6.00e+02,   4.00e+01,   1.00e-01],
#       [  5.00e+01,   6.00e+02,   4.50e+01,   1.20e+00],
#       [  5.00e+01,   8.00e+02,   4.00e+01,   4.00e-01],
#       [  5.00e+01,   8.00e+02,   4.50e+01,   2.00e-01]])

现在您可以执行三线性插值...

关于python - 如何在 NumPy 中构建三线性插值的查找表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18170782/

相关文章:

python - 目标 WSGI 脚本 '/opt/python/current/app/.../wsgi.py' 无法作为 Python 模块加载

python - 在 Jinja(Django) 中使用字典索引显示列表元素

python - numpy.random 的 Generator 类和 np.random 方法有什么区别?

arrays - 在 python 中找到长度为 n 的子序列的最小总和的最快方法

Python:为图形插值矩阵

python - 当给定非均匀样本时,如何限制 Python 中 InterpolatedUnivariateSpline 中的插值区域?

python - 有没有办法通过将 unicode 字符串转换为其他编码来打印出由 unicode 字符串组成的字典?

php - 正则表达式替换混合数字+字符串

python - 过滤直方图边缘和计数

c++ - 仅由表定义的评估函数,C++