在NumPy数组的每一行(行方式)上应用函数

时间:2021-01-20 21:21:29

So, I have the function -

所以,我有这个功能 -

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

and let's say that I would like to evaluate it at the following points (first column are the x-values and second column are the y-values) -

让我们说我想在以下几点评估它(第一列是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]])

i.e. I would like to pass the function the first row of values and evaluate, then the second row and evaluate etc. and then the final result would be an array of the values evaluated at these points (so, an array consisting of 10 values).

即我想传递函数第一行的值和评估,然后第二行和评估等,然后最终的结果将是在这些点评估的值的数组(所以,一个由10个值组成的数组) 。

So, for example, if the function was, say, a bivariate normal distribution -

因此,例如,如果函数是,例如,双变量正态分布 -

def function2(x):

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

return function2

and I passed the above values into this function, I would get -

我把上面的值传递给了这个函数,我会得到 -

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])

So basically, I am looking for a way to rewrite the function so that it can do this. Moreover, I would like to keep the function as a function of one variable only (i.e. only a function of x).

基本上,我正在寻找一种方法来重写函数,以便它可以做到这一点。此外,我想保持函数仅作为一个变量的函数(即只是x的函数)。

Thank you for your help!

感谢您的帮助!

2 个解决方案

#1


6  

You can use np.apply_along_axis:

你可以使用np.apply_along_axis:

np.apply_along_axis(function, 1, array)

The first argument is the function, the second argument is the axis along which the function is to be applied. In your case, it is the first axis. The last argument is the array, of course.

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

You should be warned, however, that apply_along_axis is only a convenience function, not a magic bullet. It has a severe speed limitation, since it just hides a loop. You should always try to vectorize your computation, where possible. Here's how I'd do this:

但是,您应该收到警告,apply_along_axis只是一个便利功能,而不是灵丹妙药。它具有严格的速度限制,因为它只是隐藏了一个循环。在可能的情况下,您应该始终尝试对计算进行矢量化。这是我如何做到这一点:

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

#2


2  

There are several ways to accomplish this, the only line you have to change is the asignment of x and y. x,y = vector only works if the first dimension of vector has length 2. (vector.shape = 2,...). So you can simply change your vector with any of the following commands:

有几种方法可以实现这一点,你必须改变的唯一方法是x和y的对齐。 x,y = vector仅在向量的第一维长度为2时有效(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

Just choose the one you like most, there might be other ways (I'm almost sure, but I guess this will suffice). The last one is by far the fastest, the others are comparable. The disatvantage of the last one however is, that it's not so easy to use it in higher dimensions.

只要选择你最喜欢的那个,可能有其他方式(我几乎可以肯定,但我想这就足够了)。最后一个是迄今为止最快的,其他的是可比的。然而,最后一个的缺点是,在更高的维度上使用它并不容易。

#1


6  

You can use np.apply_along_axis:

你可以使用np.apply_along_axis:

np.apply_along_axis(function, 1, array)

The first argument is the function, the second argument is the axis along which the function is to be applied. In your case, it is the first axis. The last argument is the array, of course.

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

You should be warned, however, that apply_along_axis is only a convenience function, not a magic bullet. It has a severe speed limitation, since it just hides a loop. You should always try to vectorize your computation, where possible. Here's how I'd do this:

但是,您应该收到警告,apply_along_axis只是一个便利功能,而不是灵丹妙药。它具有严格的速度限制,因为它只是隐藏了一个循环。在可能的情况下,您应该始终尝试对计算进行矢量化。这是我如何做到这一点:

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

#2


2  

There are several ways to accomplish this, the only line you have to change is the asignment of x and y. x,y = vector only works if the first dimension of vector has length 2. (vector.shape = 2,...). So you can simply change your vector with any of the following commands:

有几种方法可以实现这一点,你必须改变的唯一方法是x和y的对齐。 x,y = vector仅在向量的第一维长度为2时有效(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

Just choose the one you like most, there might be other ways (I'm almost sure, but I guess this will suffice). The last one is by far the fastest, the others are comparable. The disatvantage of the last one however is, that it's not so easy to use it in higher dimensions.

只要选择你最喜欢的那个,可能有其他方式(我几乎可以肯定,但我想这就足够了)。最后一个是迄今为止最快的,其他的是可比的。然而,最后一个的缺点是,在更高的维度上使用它并不容易。