如何在向量化函数中传递*args

问题描述 投票:0回答:2

对于Python中常用的

*args
技术,但功能是
np.vectorized
。通常,
*args
可以工作,但是当我对函数进行向量化并且 args 是一个向量时,它认为所有组合的行都是参数,而不是每一行都是参数。我显然可以有
my_function(a,b,c,d,e)
,但我的实际函数有很多很多输入。我如何使用
*args
技术做到这一点?

import numpy as np

a = np.random.rand(50,1)
b = np.random.rand(50,1)

args = np.random.rand(50,3)

def my_function(a,b,c,d,e):
    
    result = a * b * c * d * e
    

    return result


my_func_vec = np.vectorize(my_function)
res = my_func_vec(a,b,*args)

# TypeError: my_function() takes 5 positional arguments but 52 were given
python numpy function vector vectorization
2个回答
0
投票
import numpy as np

a = np.random.rand(50, 1)
b = np.random.rand(50, 1)

args = np.random.rand(50,3)
    
def my_function(a, b, c, d, e):
    result = a * b * c * d * e
    return result

def wrapper_func(a, b, params_row):
    return my_function(a, b, *params_row)
my_func_vec = np.vectorize(wrapper_func, signature='(),(),(n)->()')


res = my_func_vec(np.squeeze(a), np.squeeze(b), args)  #to convert (50,1) arrays to (50,) to make things compatible 
print(res)

输出:

[2.04426871e-02 6.90251979e-03 3.65811647e-02 1.64784141e-04
 4.35888426e-02 1.11680236e-03 1.77265850e-02 4.95765052e-03
 6.79152250e-05 2.40806056e-04 5.21195880e-02 1.87644160e-02
 6.10992452e-04 4.10024255e-02 5.92372496e-03 2.90534846e-02
 2.46944495e-05 2.59179190e-02 1.21266065e-02 1.77476896e-01
 9.10771238e-03 1.79067184e-03 4.19752913e-01 1.67823828e-03
 3.63713035e-02 1.27287054e-02 9.40996439e-03 8.96187745e-03
 1.56632220e-04 3.19315171e-02 4.25328030e-03 5.83103313e-03
 4.89234139e-04 8.43781021e-04 4.80337136e-04 1.90698892e-01
 2.51064668e-04 7.27973431e-02 4.58804875e-03 1.09680786e-03
 6.62614160e-02 1.38636845e-04 5.13097091e-04 3.91293968e-04
 3.93461614e-03 6.66755401e-02 1.84588850e-04 7.37273682e-02
 1.28312385e-04 1.85730481e-03]

这里的事情是 (50,1) 与你的参数部分不兼容。为了将它们组合在一起,存在可以取出的包装函数,但签名会有所不同,以便于创建一个函数进行格式化是更好的选择。


0
投票

使用

*args
将沿行解压
args
。你想沿着列做,所以你可以先转置。

my_func_vec(a, b, *args.T)

但是这个例子并不需要

np.vectorize
,你应该重新检查你的实际情况,看看是否需要它。如果没有它,代码会快得多。

%timeit my_function(a, b, *args.T)
14.8 µs ± 490 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
%timeit my_func_vec(a, b, *args.T)
468 µs ± 13.1 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
© www.soinside.com 2019 - 2024. All rights reserved.