我想从不同 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函数和方法用于power
、addition
、sqrt
等。
您的 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
中,或使用第三方软件包,例如cython
,numba
或numexpr
。