我想将函数应用于5x1 numpy数组的每一行。我正在应用的函数有两个参数,我希望数组的元素作为第二个参数输入,而不是第一个参数。我一直在使用signed long sl = 0x8000000000000000L;
。查看此功能的文档,它似乎不可能。
在没有显式定义参数顺序颠倒的新函数的情况下,是否仍然可以这样做?我只是好奇。以下是我一直在搞乱的例子。
numpy.apply_along_axis()
答案 0 :(得分:1)
我要调整你的例子,让它更有趣
In [190]: np.apply_along_axis(lol,0,tmp,2)
Out[190]: array([ 1.5, 2.5, 3.5])
In [191]: np.apply_along_axis(lol,1,tmp,2)
Out[191]: array([ 1.5, 6. ])
因此,使用2d tmp,我们可以沿任一轴应用它
lambda
另一个In [192]: np.apply_along_axis(lambda x,y:lol(y,x),0,tmp,2)
Out[192]:
array([[ inf, 2. , 1. ],
[ 0.66666667, 0.5 , 0.4 ]])
干净地切换参数:
2/tmp
(与lambda
相同;轴并不重要)
函数调用的额外层并没有太多改变执行速度(切换参数会增加时间,但我想关注额外In [195]: timeit np.apply_along_axis(lol,1,tmp,2)
10000 loops, best of 3: 103 us per loop
In [196]: timeit np.apply_along_axis(lambda x,y:lol(x,y),1,tmp,2)
10000 loops, best of 3: 105 us per loop
的影响。)
apply_along_axis
使用apply_along_axis
没有什么神奇或额外的效率;你(或我们)可以写一个做同样事情的迭代。
让我们比较2个表达式,In [213]: np.apply_along_axis(lol,0,tmp,2)
Out[213]: array([ 1.5, 2.5, 3.5])
In [214]: np.array([lol(tmp[:,i],2) for i in range(tmp.shape[1])])
Out[214]: array([ 1.5, 2.5, 3.5])
In [215]: timeit np.apply_along_axis(lol,0,tmp,2)
10000 loops, best of 3: 132 us per loop
In [217]: timeit np.array([lol(tmp[:,i],2) for i in range(tmp.shape[1])])
10000 loops, best of 3: 64.1 us per loop
和等效列表理解:
apply_along_axis
var elem=function(pos){return arr[pos];}
elem(0) //"a"
elem(1) //"b"
arr.splice(1,1);
elem(1) //"c"
速度较慢,可能是因为它试图更加通用。它可能更方便,但它显然更有效率。
答案 1 :(得分:0)
有可能!但是函数本身是直接调用的,数据是第一个参数(参见source),所以你需要另一层抽象来改变参数:例如使用装饰器:
from functools import wraps
def swapelements(func):
@wraps(func)
def wrapper(array, *args, **kwargs):
# Insert the array as second=array:
kwargs['second'] = array
return func(*args, **kwargs)
return wrapper
np.apply_along_axis(swapelements(lol), 1, tmp, first=1)
array([[ 6.24582532], [ 1.14800413], [ 1.87634432], [ 14.31209963], [ 2.47123623]])
tmp
为[[ 0.16010694], [ 0.871077 ], [ 0.53295122], [ 0.06987095], [ 0.40465577]]
如果您使用5x1
数组,为什么要使用apply_along_axis
?你可以通过使用:
result = 1. / tmp
您的第二个轴只包含一个元素。