Python 在 NumPy 数组的每一行(逐行)上应用函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/45604688/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 17:09:47  来源:igfitidea点击:

Apply function on each row (row-wise) of a NumPy array

pythonarraysnumpyapply

提问by tattybojangler

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!

感谢您的帮助!

回答by cs95

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_axisis 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只是一个方便的功能,而不是灵丹妙药。它有一个严重的速度限制,因为它只是隐藏了一个循环。在可能的情况下,您应该始终尝试矢量化您的计算。这是我如何做到这一点:

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

回答by Jürg Merlin Spaak

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

有几种方法可以实现这一点,唯一需要更改的行是xand的分配yx,y = vector仅当 的第一个维度的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.

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