如何将2D查找表映射到数组中(Python)?

3

我有三个形状相同的二维数组,分别称为theta、phi和A。 让theta和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是一个二维测量值的地图,其中x轴表示theta,y轴表示phi,以已知且线性间隔为步长(实际上不同于theta和phi的形状)。我需要的是将A(theta, phi)表达为A(x,y)。

尽管我知道了theta(x,y)和phi(x,y),但似乎我无法想出如何将A(theta, phi)转换为A(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(theta,phi)轴的范围大于theta(x,y)和phi(x,y)的范围,因此始终存在映射值。 我不需要将B映射回A,所以不存在缺失值的问题。 在地图A(theta, 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值,我可以通过查找表中的对应phi值来确定: theta[i,j]对应于phi[i,j]。但是这个示例的构建过于简化,它们没有共享相同的原点,数据也很嘈杂,因此我无法给出theta(phi)或phi(theta)的解析表达式。

2)我的实际theta和phi值是浮点数,并且我的实际A也在非整数步长(例如,theta方向每步0.45度,phi方向每步0.2度)上进行测量。

3)原则上,由于theta和phi之间存在严格关系,我只需要找到特定的一维“A值”跟踪即可找到B,但我不知道如何找到这个跟踪,也不知道如何将其转换为B。 在这个示例中,这个跟踪将是[A[0,0],A[4,1],A[5,1],A[6,2]] = [0.0,4.1,5.1,6.2]。


θ (x₀, y₀) ≠ θ (x₁, y₁) 有限制吗?phi也是如此,A在(θ,ϕ)和(x,y)中也是如此吗?如果没有,那么为什么你能够进行这种反向转换,因为在反向方向上可能会有多个匹配值。 - Dan
我指的是,例如A(4,7)可能等于A(8,2),因此在给定A的值时,您如何知道是否要映射回(4,7)或(8,2)? - Dan
1
问题仍然有些不清楚。1)鉴于您始终可以计算出phi,反之亦然。那么为什么不将其简化为一维问题呢?2)“以A(theta,phi)表示为A(x,y)的值”确切地意味着什么?您是指,鉴于(theta,phi),您想知道(x,y)吗?3)也许可以添加一个“A”的玩具示例? - Andrei
感谢您的评论,Andrei。我尝试用一个小玩具示例来解决它们。这很难解释,我非常感谢您帮助指出最难理解的部分。 - fruchti
这是正确的 - fruchti
显示剩余3条评论
1个回答

3

你可以执行双线性插值:

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]]

抱歉回复和接受晚了,上周我忙于其他事情。这正是我在寻找的。再次感谢您帮助澄清我的问题,因为它有点难以理解。 - fruchti

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接