gpt4 book ai didi

python - 将函数向量应用于参数向量

转载 作者:太空宇宙 更新时间:2023-11-04 00:46:06 25 4
gpt4 key购买 nike

我想接受一个函数列表,funclist ,并返回一个接受参数列表的新函数,arglist , 并应用 i funclist 中的第一个函数到 i arglist 的第一个元素, 返回列表中的结果:

def myfunc(funclist):
return lambda arglist: [ funclist[i](elt) for i, elt in enumerate(arglist) ]

这并未针对 funclist 中独立函数的并行/矢量化应用进行优化argvec中的独立参数. python 或 numpy(或其他)中是否有内置函数将返回 lambda 的更优化版本?多于?它在精神上类似于 mapnumpy.vectorize (但显然不一样),到目前为止我还没有找到任何东西。

最佳答案

numpy 术语中,真正的矢量化意味着在编译代码中执行迭代操作。通常这需要使用处理整个数组的 numpy 函数,执行诸如加法和索引之类的操作。

np.vectorize 是一种迭代多个数组并在不处理数组的函数中使用它们的元素的方法。它在编译后的代码中作用不大,因此不会大大提高速度。作为将 numpy 广播规则应用于您自己的标量函数的一种方式,它是最有值(value)的。

map 是列表理解的变体,速度基本相同。列表理解具有更强的表达能力,可以处理多个列表。

@Tore 的 压缩理解清楚地表达了这个任务

[f(args) for f, args in zip(funclist, arglist)]

map 可以处理多个输入列表:

In [415]: arglist=[np.arange(3),np.arange(1,4)]
In [416]: fnlist=[np.sum, np.prod]
In [417]: [f(a) for f,a in zip(fnlist, arglist)]
Out[417]: [3, 6]
In [418]: list(map(lambda f,a: f(a), fnlist, arglist))
Out[418]: [3, 6]

您的版本有点冗长,但功能相同。

In [423]: def myfunc(funclist):
...: return lambda arglist: [ funclist[i](elt) for i, elt in enumerate(arglist) ]

In [424]: myfunc(fnlist)
Out[424]: <function __main__.myfunc.<locals>.<lambda>>
In [425]: myfunc(fnlist)(arglist)
Out[425]: [3, 6]

它的优点是生成可应用于不同参数列表的函数:

In [426]: flist=myfunc(fnlist)
In [427]: flist(arglist)
Out[427]: [3, 6]
In [428]: flist(arglist[::-1])
Out[428]: [6, 0]

我会这样写 myfunc:

def altfun(funclist):
def foo(arglist):
return [f(a) for f,a in zip(funclist, arglist)]
return foo

但差异只是风格上的。

================

zip v enumerate 的时间测试:

In [154]: funclist=[sum]*N
In [155]: arglist=[list(range(N))]*N
In [156]: sum([funclist[i](args) for i,args in enumerate(arglist)])
Out[156]: 499500000
In [157]: sum([f(args) for f,args in zip(funclist, arglist)])
Out[157]: 499500000

In [158]: timeit [funclist[i](args) for i,args in enumerate(arglist)]
10 loops, best of 3: 43.5 ms per loop

In [159]: timeit [f(args) for f,args in zip(funclist, arglist)]
10 loops, best of 3: 43.1 ms per loop

基本相同。但是 map 快 2 倍

In [161]: timeit list(map(lambda f,a: f(a), funclist, arglist))
10 loops, best of 3: 23.1 ms per loop

将迭代打包到可调用对象中也更快

In [165]: timeit altfun(funclist)(arglist)
10 loops, best of 3: 23 ms per loop
In [179]: timeit myfunc(funclist)(arglist)
10 loops, best of 3: 22.6 ms per loop

关于python - 将函数向量应用于参数向量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39535756/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com