对NumPy数组的每一行(按行)应用函数

70

所以,我有这个函数 -

def function(x):
    x , y = vector
    return exp(((-x**2/200))-0.5*(y+0.05*(x**2) - 100*0.05)**2)

假设我想在以下点(第一列是x值,第二列是y值)处对其进行评估 -

array([[-1.56113514,  4.51759732],
       [-2.80261623,  5.068371  ],
       [ 0.7792729 ,  6.0169462 ],
       [-1.35672858,  3.52517478],
       [-1.92074891,  5.79966161],
       [-2.79340321,  4.73430001],
       [-2.79655868,  5.05361163],
       [-2.13637747,  5.39255837],
       [ 0.17341809,  3.60918261],
       [-1.22712921,  4.95327158]])

我希望将该函数的第一行值传递给它进行评估,然后是第二行并进行评估,以此类推。最终结果将是在这些点上评估的值的数组(因此,由10个值组成的数组)。
例如,如果该函数是双变量正态分布-
def function2(x):

function2 = (mvnorm.pdf(x,[0,0],[[1,0],[0,1]]))

return function2

如果我将上述值传递到此函数中,则会得到 -

array([  1.17738907e-05,   1.08383957e-04,   1.69855078e-04,
         5.64757613e-06,   1.37432346e-05,   1.44032800e-04,
         1.33426313e-05,   1.97822328e-06,   6.56121709e-08,
         4.67076770e-05])

基本上,我正在寻找一种重写函数的方法,使其能够做到这一点。此外,我想将功能仅保留为一个变量的功能(即仅作为x的函数)。

感谢您的帮助!

2个回答

101
你可以使用 np.apply_along_axis
np.apply_along_axis(function, 1, array)

第一个参数是函数,第二个参数是应用该函数的轴。在你的情况下,它是第一个轴。最后一个参数是数组,当然。


不过要注意,apply_along_axis 只是一个方便的函数,而不是一个万能的解决方法。它有严重的速度限制,因为它只是隐藏了循环。在可能的情况下,你应该总是尝试向量化你的计算。以下是我如何实现这一点:

v = array[:, 0] ** 2   # computing just once  
return np.exp((-v / 200) - 0.5 * (array[:, 1] + 0.05 * v - 5) ** 2)

有没有办法仅更改函数以便我可以将值传递给它?不幸的是,我无法使用您的方法(但它很有用,我会记住!) - tattybojangler
@tattybojangler 你可以使用numpy数组,但不能使用numpy函数? - cs95
我无法使用它,因为我只想改变函数的定义方式。 - tattybojangler
1
@tattybojangler 你可以将其向量化:np.exp((-array[:, 0] ** 2 / 200) - 0.5 * (array[:, 1] + 0.05 * (array[:, 0]**2) - 100 * 0.05)**2) - cs95

1

有几种方法可以实现这一点,你只需要改变 xy 的赋值语句即可。只有当 vector 的第一个维度的长度为2时,x,y = vector才有效。(vector.shape = 2,...)。因此,您可以使用以下任何命令之一来更改向量:

x,y = vector.T #transpose the array
x,y = vector.swapaxes(0,1) #swap the axis 0 and 1
x,y = np.rollaxis(vector,1) #roll the axis 1 to the front
x,y = vector[:,0], vector[:,1] #slice asignement

只需选择您最喜欢的那个,可能还有其他方法(我几乎可以确定,但我想这已经足够了)。最后一个是迄今为止最快的,其他的则相当。然而,最后一个的缺点是,在更高的维度中使用它并不容易。


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