首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >向量化函数无法评估

向量化函数无法评估
EN

Stack Overflow用户
提问于 2022-01-05 15:38:22
回答 1查看 49关注 0票数 1

我遇到了一个矢量化函数的问题:

代码语言:javascript
复制
def func(y):
    return sum(x**(-y) for x in range(1, 10))
vect_func = np.vectorize(func)
vect_func([1, 2, 3, 4, 5])

# Output:
# ValueError: Integers to negative integer powers are not allowed.

然而,下面的工作原理很好:

代码语言:javascript
复制
[func(t) for t in [1, 2, 3, 4, 5]]

# Output:
# [2.8289682539682537, 1.5397677311665408, 1.1965319856741932, 1.0819365834937567, 1.0368973413446938]

是否有可能让np.vectorize在这个示例中工作?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-05 16:28:17

当函数在np.vectorize中不工作时,验证参数是什么是个好主意。

让我们向函数添加一个type打印:

代码语言:javascript
复制
In [36]: def func(y):
    ...:     print(type(y))
    ...:     return sum(x**(-y) for x in range(1, 10))
    ...: 

在列表理解中,Python int被传递:

代码语言:javascript
复制
In [37]: func(3)
<class 'int'>
Out[37]: 1.1965319856741932

使用vectorized版本:

代码语言:javascript
复制
In [40]: vect_func(3)
<class 'numpy.int64'>
Traceback (most recent call last):
  File "<ipython-input-40-65e2816d8003>", line 1, in <module>
    vect_func(3)
  File "/usr/local/lib/python3.8/dist-packages/numpy/lib/function_base.py", line 2163, in __call__
    return self._vectorize_call(func=func, args=vargs)
  File "/usr/local/lib/python3.8/dist-packages/numpy/lib/function_base.py", line 2241, in _vectorize_call
    ufunc, otypes = self._get_ufunc_and_otypes(func=func, args=args)
  File "/usr/local/lib/python3.8/dist-packages/numpy/lib/function_base.py", line 2201, in _get_ufunc_and_otypes
    outputs = func(*inputs)
  File "<ipython-input-36-311d525a60ba>", line 3, in func
    return sum(x**(-y) for x in range(1, 10))
  File "<ipython-input-36-311d525a60ba>", line 3, in <genexpr>
    return sum(x**(-y) for x in range(1, 10))
ValueError: Integers to negative integer powers are not allowed.

y不是python int,它是numpy int。

代码语言:javascript
复制
In [41]: func(np.int64(3))
<class 'numpy.int64'>
Traceback (most recent call last):
  File "<ipython-input-41-c34830937ffd>", line 1, in <module>
    func(np.int64(3))
  File "<ipython-input-36-311d525a60ba>", line 3, in func
    return sum(x**(-y) for x in range(1, 10))
  File "<ipython-input-36-311d525a60ba>", line 3, in <genexpr>
    return sum(x**(-y) for x in range(1, 10))
ValueError: Integers to negative integer powers are not allowed.

如果我们故意传递Python int,它就能工作:

代码语言:javascript
复制
In [42]: vect_func(np.array([1,2,3], object))
<class 'int'>
<class 'int'>
<class 'int'>
<class 'int'>
Out[42]: array([2.82896825, 1.53976773, 1.19653199])

当将几个数组传递给一个标量函数时,np.vectorize非常方便,而且您希望利用broadcasting。但是对于一个列表,或者可以压缩的列表,它不会给列表的理解增加任何东西--甚至是速度。

正如这个案例所说明的,它有一些缺点,无法抓住新手(甚至更有经验的用户)。这是输入的本质。对于其他许多这样的问题,这是返回值(自动otypes)的本质。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70595599

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档