如何从其他 numpy 数组上的逐元素自定义计算中返回数组?



我想从不同 numpy 数组的逐元素计算中获得一个 numpy 数组。截至目前,我正在使用 lambda 函数返回一个值,对所有值重复该值,从中创建列表,并转换为 numpy 数组:

import math
import numpy as np 
def weightAdjLoads(loadsX, loadsY, angles, g):
adjust = lambda x, y, a: math.sqrt((abs(x) - math.sin(a)*g)**2 + (abs(y) - math.cos(a)*g)**2)
return np.array([adjust(x, y, a) for x, y, a in zip (loadsX, loadsY, angles)])

在我看来,这似乎开销太大了。有没有可以做到这一点的 numpy 例程?

我知道像numpy.sqrt(A**2 + B**2(这样的方法,其中A和B是numpy数组。但是,这些只允许应用预定义的公式。如何在 numpy 数组上应用自定义公式?

numpy.sqrt(A**2 + B**2)被Python解释器解析为调用,大致如下:

tmp1 = A**2  # A.__pow__(2)
tmp2 = B**2  #
tmp3 = tmp1 + tmp2  # tmp1.__add__(tmp2)
tmp4 = np.sqrt(tmp3)

也就是说,有定义的numpy函数和方法用于poweradditionsqrt等。

您的 lambda 适用于标量,而不是 numpy 数组:

math.sqrt((abs(x) - math.sin(a)*g)**2 + (abs(y) - math.cos(a)*g)**2)

具体来说,math三角函数需要标量。abs适用于数组:

abs(A) => A.__abs__()

numpy提供了一整套 trig 函数,因此此函数应与数组或标量参数一起使用:

def foo(x, y, a):
return np.sqrt((abs(x) - np.sin(a)*g)**2 + (abs(y) - np.cos(a)*g)**2)

有一些方法可以将标量adjust包装到 numpy 函数中,但相对于列表理解的速度节省很小。

f = np.vectorize(adjust)
f = np.frompyfunc(adjust, 3, 1)

主要是它们使将数组broadcast为标量函数变得更加容易。 但是要获得compiled速度,您必须进行转换,例如在我的foo中,或使用第三方软件包,例如cythonnumbanumexpr

最新更新