Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将3参数函数应用于三维numpy数组_Python_Numpy - Fatal编程技术网

Python 将3参数函数应用于三维numpy数组

Python 将3参数函数应用于三维numpy数组,python,numpy,Python,Numpy,我有一个形状为(2133,3,3)的3D numpy数组。基本上,这是一个包含2133个列表和三个3D点的列表。此外,我还有一个函数,它获取三个3D点并返回一个3D点,x=f(a,b,c),其中a,b,c,x numpy数组长度为3。现在我想将f应用于A,这样输出就是一个shape数组(2133,3)。所以类似于numpy.array([f(*A[0]),…,f(*A[2132]) 我尝试了numpy。沿_轴应用_和numpy。矢量化,但没有成功 更确切地说,我考虑的函数是: def f(a,

我有一个形状为(2133,3,3)的3D numpy数组。基本上,这是一个包含2133个列表和三个3D点的列表。此外,我还有一个函数,它获取三个3D点并返回一个3D点,
x=f(a,b,c)
,其中a,b,c,x numpy数组长度为3。现在我想将f应用于A,这样输出就是一个shape数组(2133,3)。所以类似于
numpy.array([f(*A[0]),…,f(*A[2132])

我尝试了
numpy。沿_轴应用_
numpy。矢量化
,但没有成功

更确切地说,我考虑的函数是:

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
这很好(在注释掉
sort\u triple
之后):

制作:

[array([ 132.21182324,   23.80481826,    1.43482849]), None]
这看起来像是一行产生了一个(3,)另一个数组出现了某种问题,并产生了
None
。我不知道
None
是否是由于删除了排序。但在任何情况下,将数组和
None
的混合返回到一个数组将是一个问题。如果
res
的所有项都匹配数组,我们可以
stack
将它们返回转换为二维数组

有一些方法可以获得适度的速度提升(与列表理解相比)。但是对于这样一个复杂的函数,在函数中花费的时间(称为2000次)占迭代机制花费的时间的主导地位

由于您在第1维上迭代,并传递其他2维(作为3个数组),因此此显式循环比
矢量化
frompyfunc
沿..
应用要容易得多


为了节省大量时间,您必须编写
f()
来直接使用3d阵列。

多亏了@jdehesa的大力帮助,我能够生成一个替代@hpaulj给出的解决方案。我不确定此解决方案是否是最优雅的解决方案,但迄今为止它仍然有效。欢迎评论

def sort_triple(a, b, c):
    pts = np.stack((a, b, c), axis=1)
    xSorted = pts[np.arange(pts.shape[0])[:, None], np.argsort(pts[:, :, 0])]
    orientation = np.cross(xSorted[:, 1] - xSorted[:, 0], xSorted[:, 2] -
                           xSorted[:, 0])[:, 2] >= 0
    xSorted_flipped = np.stack((xSorted[:, 0], xSorted[:, 2], xSorted[:, 1]),
                               axis=1)
    xSorted = np.where(orientation[:, np.newaxis, np.newaxis], xSorted,
                       xSorted_flipped)
    return map(np.squeeze, np.split(xSorted, 3, axis=1))


def f(A, r1, r2=None, r3=None):

    a, b, c = map(np.squeeze, np.split(A, 3, axis=1))
    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, axis=1))[:, np.newaxis]
    i = inner1d(ex, (c - a))
    ey = ((c - a - i[:, np.newaxis]*ex) /
          (np.linalg.norm(c - a - i[:, np.newaxis]*ex, axis=1))[:, np.newaxis])
    ez = np.cross(ex, ey)
    d = np.linalg.norm(b - a, axis=1)
    j = inner1d(ey, c - a)

    x = (np.square(r1) - np.square(r2) + np.square(d)) / (2 * d)
    y = ((np.square(r1) - np.square(r3) + np.square(i) + np.square(j)) / (2*j) -
         i/j*x)
    z_square = np.square(r1) - np.square(x) - np.square(y)
    mask = z_square < 0
    z_square[mask] *= 0
    z = np.sqrt(z_square)
    z[mask] = np.nan
    intersection = (a + x[:, np.newaxis] * ex + y[:, np.newaxis] * ey +
                    z[:, np.newaxis] * ez)
    return intersection
def sort_三重(a、b、c):
pts=np.堆栈(a、b、c),轴=1)
xSorted=pts[np.arange(pts.shape[0])[:,None],np.argsort(pts[:,:,0])]
方向=np.cross(xSorted[:,1]-xSorted[:,0],xSorted[:,2]-
X排序[:,0])[:,2]>=0
xSorted_fliped=np.stack((xSorted[:,0],xSorted[:,2],xSorted[:,1]),
轴=1)
xSorted=np.where(方向[:,np.newaxis,np.newaxis],xSorted,
X排序(翻转)
返回映射(np.Squence,np.split(X排序,3,轴=1))
def f(A、r1、r2=无,r3=无):
a、 b,c=映射(np.挤压,np.分裂(a,3,轴=1))
a、 b,c=排序三(a,b,c)
如果有(对于(r2,r3)中的r,r为无):
r2,r3=(r1,r1)
ex=(b-a)/(np.linalg.norm(b-a,axis=1))[:,np.newaxis]
i=内部1d(例如,(c-a))
ey=((c-a-i[:,np.newaxis]*ex)/
(np.linalg.norm(c-a-i[:,np.newaxis]*ex,axis=1))[:,np.newaxis])
ez=np.交叉(例如,ey)
d=np.linalg.norm(b-a,轴=1)
j=1d(ey,c-a)
x=(np平方(r1)-np平方(r2)+np平方(d))/(2*d)
y=((np.平方(r1)-np.平方(r3)+np.平方(i)+np.平方(j))/(2*j)-
i/j*x)
z_平方=np.平方(r1)-np.平方(x)-np.平方(y)
掩码=z_平方<0
z_平方[掩码]*=0
z=np.sqrt(z_平方)
z[mask]=np.nan
交点=(a+x[:,np.newaxis]*ex+y[:,np.newaxis]*ey+
z[:,np.newaxis]*ez)
返回交叉口

可能每个函数中的
map
部分可以做得更好。也可能过度使用
np.newaxis

看看你用
np尝试了什么。矢量化
np.apply_沿_轴
会很有帮助。另外,函数f到底有什么作用?你可以用矢量化的版本替换它。@user2699我提供了函数
f
。我认为
np.apply\u沿轴
的问题在于它沿给定轴应用于1D切片。
np.vectorize
不起作用,因为解包没有以正确的方式完成。即使我重写
f
,使其具有形状数组(3,3),我该如何告诉numpy在第一个轴上迭代并获取3x3子阵列?没有自动的方法可以做到这一点,您需要编写
f
,使其与点阵列而不是单个点一起工作。我认为这几乎是可以的,尽管您需要更改第一个
if
,但在>代码> No.Limal.MultUng/Mult>调用和可能的一些东西(<代码> SotTyTrime3/代码>,我假设它是另一个如果你的函数也需要修改的话。BTW,考虑替换每个<代码> PoW(x,2)< /Cube >调用<代码> NP.x(平方)(x)< /Cord>。HijJeHESA你到底指的是什么意思?“您需要以一种方式来编写f,使其与点数组而不是单点一起工作。”通过
p
a、b、c
替换为参数,其中
p
是一个形状数组(3,3),然后解包
p
似乎不起作用。你的意思是
f
的输入参数的形状必须与
A
的形状相同,至少有三个维度?感谢
np.square(x)
@patrik的提示否,我的意思是函数必须设计为采用三个形状为(2133,3)(或(X,3)并直接返回(2133,3)结果。例如,您需要将
ex=(b-a)/(np.linalg.norm(b-a))
更改为
ex=(b-a)/(np.linalg.norm(b-a,axis=0))
,等等。每个语句必须同时处理所有点。没有通用的自动化方法(也就是说,如果性能不是一个大问题,那么为了方便起见,可以使用循环或理解)。谢谢@hpaulj。f确实可能产生一个“无”。f计算三个点的三边测量点,有时对于给定的
r1
,它根本不存在。性能是什么
def sort_triple(a, b, c):
    pts = np.stack((a, b, c), axis=1)
    xSorted = pts[np.arange(pts.shape[0])[:, None], np.argsort(pts[:, :, 0])]
    orientation = np.cross(xSorted[:, 1] - xSorted[:, 0], xSorted[:, 2] -
                           xSorted[:, 0])[:, 2] >= 0
    xSorted_flipped = np.stack((xSorted[:, 0], xSorted[:, 2], xSorted[:, 1]),
                               axis=1)
    xSorted = np.where(orientation[:, np.newaxis, np.newaxis], xSorted,
                       xSorted_flipped)
    return map(np.squeeze, np.split(xSorted, 3, axis=1))


def f(A, r1, r2=None, r3=None):

    a, b, c = map(np.squeeze, np.split(A, 3, axis=1))
    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, axis=1))[:, np.newaxis]
    i = inner1d(ex, (c - a))
    ey = ((c - a - i[:, np.newaxis]*ex) /
          (np.linalg.norm(c - a - i[:, np.newaxis]*ex, axis=1))[:, np.newaxis])
    ez = np.cross(ex, ey)
    d = np.linalg.norm(b - a, axis=1)
    j = inner1d(ey, c - a)

    x = (np.square(r1) - np.square(r2) + np.square(d)) / (2 * d)
    y = ((np.square(r1) - np.square(r3) + np.square(i) + np.square(j)) / (2*j) -
         i/j*x)
    z_square = np.square(r1) - np.square(x) - np.square(y)
    mask = z_square < 0
    z_square[mask] *= 0
    z = np.sqrt(z_square)
    z[mask] = np.nan
    intersection = (a + x[:, np.newaxis] * ex + y[:, np.newaxis] * ey +
                    z[:, np.newaxis] * ez)
    return intersection