我有一个形状(2133,3,3)的3D numpy阵列A.基本上这是包含三个3D点的2133个列表的列表。此外,我有一个函数需要三个三维点,并返回一个三维点,x = f(a, b, c)
,长度为3的a,b,c,x numpy数组。现在我想将f应用于A,以便输出是一个形状数组(2133,3)。所以像numpy.array([f(*A[0]),...,f(*A[2132]))
。将三参数函数应用到3D numpy阵列
我试过numpy.apply_along_axis
和numpy.vectorize
没有成功。
更精确的函数f我考虑的是由下式给出:
def f(a, b, c, r1, r2=None, r3=None):
a = np.asarray(a)
b = np.asarray(b)
c = np.asarray(c)
if np.linalg.matrix_rank(np.matrix([a, b, c])) != 3:
# raise ValueError('The points are not collinear.')
return None
a, b, c, = sort_triple(a, b, c)
if any(r is None for r in (r2, r3)):
r2, r3 = (r1, r1)
ex = (b - a)/(np.linalg.norm(b - a))
i = np.dot(ex, c - a)
ey = (c - a - i*ex)/(np.linalg.norm(c - a - i*ex))
ez = np.cross(ex, ey)
d = np.linalg.norm(b - a)
j = np.dot(ey, c - a)
x = (pow(r1, 2) - pow(r2, 2) + pow(d, 2))/(2 * d)
y = ((pow(r1, 2) - pow(r3, 2) + pow(i, 2) + pow(j, 2))/(2*j)) - ((i/j)*x)
z_square = pow(r1, 2) - pow(x, 2) - pow(y, 2)
if z_square >= 0:
z = np.sqrt(z_square)
intersection = a + x * ex + y*ey + z*ez
return intersection
A = np.array([[[131.83, 25.2, 0.52], [131.51, 22.54, 0.52],[133.65, 23.65, 0.52]], [[13.02, 86.98, 0.52], [61.02, 87.12, 0.52],[129.05, 87.32, 0.52]]])
r1 = 1.7115
看到你用'np.vectorize'和'np.apply_along_axis'试过会有帮助。另外,函数f究竟做了什么?您可能可以用矢量化版本替换它。 – user2699
@ user2699我提供了函数f。我认为'np.apply_along_axis'的问题在于,它被应用于给定轴上的一维切片。 'np.vectorize'不起作用,因为解包不是以正确的方式完成的。即使我重写'f',以便它需要一个形状数组(3,3),我如何告诉numpy迭代第一个轴并采用3x3子阵列? – patrik
有没有自动的方法来做到这一点,你需要写一个'f'的方式来处理点数组而不是单点。我认为它几乎没问题,虽然你需要改变第一个'if',给'np.linalg.norm'调用添加一个'axis'参数,可能还有更多的东西('sort_triple',我假设它是另一个如果你的功能,可能需要适应)。顺便说一句,考虑用'np.square(x)'替换每个'pow(x,2)'调用。 – jdehesa