以下摘录是我试图为其构建 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 行表,以便可以对其非线性数据进行插值并根据用户输入获取正确的值?
澄清
- 如果用户输入以下向量 (775, 47, 41.3),程序应返回以下四个向量之间的插值:
45.0, 600, 0.2, 1.7
,45.0 、800、0.8、0.4
、50.0、600、0.1、1.2
和50.0、800、0.4、0.2
- 假设数据将从数据库中提取为您设计的 numpy 数组
最佳答案
我发现的第一个困难是 <=
和>=
,我可以处理 Density
的四肢复制,并将其值更改为非常接近的虚拟值 99
和1601
,这不会影响插值。
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/