如何将二维查找表映射到数组(python)



我有三个形状相同的2D数组,我们称它们为θ、phi和A。设θ和phi是从表面上不同距离看到的法向量的角度:

size = 100 # this value is fixed
x = np.arange(-size, size)
y = np.arange(-size, size)
xx, yy = np.meshgrid(xx, yy)
theta = np.arctan((xx**2+yy**2)**0.5 / 100) # angle from distance 100
phi = np.arctan((xx**2+yy**2)**0.5 / 1000) # angle from distance 1000

设A是测量值的2D映射,其中x轴是θ,y轴是φ,以已知的线性步长(实际上与θ和φ的形状不同(。我需要的是A(θ,phi(的值,表示为A(x,y(。我似乎不知道如何将A(theta,phi(转换为A(x,y(,尽管我知道theta(x,y(和phi(x,y(。

我尝试过的:通过scipy.interpolate.interp2d,我可以将A映射到与theta和phi相同数量的行和列。现在我可以迭代索引,并猜测/舍入数组中最匹配的索引

B = np.zeros(A.shape)
for i in range(0,A.shape[0]):
for j in range(0,A.shape[1]):
B[i,j] = A[int(f_theta*theta[i,j]),int(f_phi*phi[i,j])]

其中f_theta和f_phi是由索引步长的测量步长确定的前置因子。对我来说,这看起来像是非常糟糕和低效的编码,就像是我实际想要做的事情的粗略近似(哪是逆插值映射?(。它让我想起了查找表、坐标变换和插值,但没有这些关键字,我找到了适合解决问题的方法。我的python经验表明,会有一个我不知道的模块/函数。

编辑有关限制:轴在A(θ,phi(中的范围大于θ(x,y(和phi(x,y(的范围,使得映射值总是存在。我不需要将B映射回A,因此不存在缺少值的问题。映射A中的许多值(θ,phi(将永远不会被使用。

关于清晰度的编辑:我将举一个小矩阵的例子,希望能澄清一下:

# phi given in degrees
phi = np.array([
[2,1,2],
[1,0,1],
[2,1,2],
])
# theta given in degrees
theta = np.array([
[6,4,6],
[4,0,5],
[6,5,6],
])
# A[0,0] is the value at phi=0deg, theta=0deg
# A[0,1] is the value at phi=1deg, theta=0deg
# A[1,1] is the value at phi=1deg, theta=1deg etc
# this is a toy example, the actual A cannot be constructed by a simple rule
A = np.array([
[0.0,0.1,0.2],
[1.0,1.1,1.2],
[2.0,2.1,2.2],
[3.0,3.1,3.2],
[4.0,4.1,4.2],
[5.0,5.1,5.2],
[6.0,6.1,6.2],
])
# what I want to reach:
B = [[6.2,4.1,6.2],
[4.1,0.0,5.1],
[6.2,5.1,6.2]]

我需要澄清的是,我在这里做了一些简化:

1( 对于给定的θ,我可以通过查找表来检查相应的φ:theta[i,j]对应于phi[i,j]。但是这个例子的结构过于简化,它们不共享同一个原点,这是有噪声的数据,因此我不能给出分析表达式θ(phi(或φ(theta(

2( 我的实际θ和phi中的值是浮动的,我的实际A也以非整数步长测量(例如,θ方向每步长0.45度,phi方向每步长0.2度(

3( 原则上,由于θ和phi之间有严格的关系,我只需要值a的特定1D"轨迹"就可以找到B,但我不知道如何找到这个轨迹,也不知道如何从轨迹中创建B。本例中的该轨迹为[A[0,0],A[4,1],A[5,1],A[6,2]]=[0.0.4.1,5.1,6.2]

例如,您可以执行双线性插值:

from scipy.interpolate import interpn
delta = [1.0, 1.0] # theta, phi
points = [np.arange(s)*d for s, d in zip(A.shape, delta)]
xi = np.stack((theta, phi), axis = -1)
B = interpn(points, A, xi)

这给出:

print(B)
[[6.2 4.1 6.2]
[4.1 0.  5.1]
[6.2 5.1 6.2]]

最新更新