简体   繁体   English

制作标量 python function 接受列表和 arrays

[英]make scalar python function accept list and arrays

In python, is there an easy and efficient way to make function f(x: float) accept both lists and numpy arrays as arguments (in which case I would want to apply f element-wise and return the result in the same format as it was sent in)? In python, is there an easy and efficient way to make function f(x: float) accept both lists and numpy arrays as arguments (in which case I would want to apply f element-wise and return the result in the same format as it已发送)? For now, I need only 1-dimensional arrays.现在,我只需要一维 arrays。

As an illustration (my real f is more complex), let's say that I have:作为一个例子(我的真实f更复杂),假设我有:

def f(x):
    return math.log(x) if x > 0 else 0.0

Then this one works, but is not that elegant - and possibly not that efficient either, because of the recursion (which I use as it allows me to have just one function):然后这个工作,但不是那么优雅 - 也可能不是那么有效,因为递归(我使用它,因为它允许我只有一个函数):

def f(x):
    if np.isscalar(x):
        return math.log(x) if x > 0 else 0.0
    elif isinstance(x, np.ndarray):
        return np.array([f(i) for i in x], dtype=float)
    else:
        return [f(i) for i in x]

Is there a better way?有没有更好的办法?

Using a decorator function would be a good option if this is something you'd need to for more than just a single function definition in your code-base.如果您需要的不仅仅是代码库中的单个 function 定义,那么使用装饰器 function 将是一个不错的选择。 It does mean that you have to wrap your code, but I'm assuming that what you mean by "having just one function" is that you do want the function expression in f(x) to be the same for all cases.这确实意味着您必须包装您的代码,但我假设您所说的“只有一个函数”的意思是您确实希望 f(x) 中的 function 表达式在所有情况下都相同。

Using your existing code, the decorator function would look like this:使用您现有的代码,装饰器 function 将如下所示:

def elementwise_possible(func):
    def wrapper(x):
        if np.isscalar(x):
            return func(x)
        elif isinstance(x, np.ndarray):
            return np.array([func(i) for i in x], dtype=float)
        else:
            return [func(i) for i in x]
    return wrapper 

And you would write your function like this:你会这样写你的 function :

@elementwise_possible
def f(x):
    return math.log(x) if x > 0 else 0.0

The resulting output becomes结果 output 变为

In[2]: A = f(2)
In[3]: A
Out[3]: 0.6931471805599453

In[4]: B = f(np.array([2,3,4]))
In[5]: B
Out[5]: array([0.69314718, 1.09861229, 1.38629436])

In[6]:C = f([5,6,7])
In[7]:C
Out[7]: [1.6094379124341003, 1.791759469228055, 1.9459101490553132]

I think efficiency should be the same.我认为效率应该是一样的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM