我遇到了一个矢量化函数的问题:
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.然而,下面的工作原理很好:
[func(t) for t in [1, 2, 3, 4, 5]]
# Output:
# [2.8289682539682537, 1.5397677311665408, 1.1965319856741932, 1.0819365834937567, 1.0368973413446938]是否有可能让np.vectorize在这个示例中工作?
发布于 2022-01-05 16:28:17
当函数在np.vectorize中不工作时,验证参数是什么是个好主意。
让我们向函数添加一个type打印:
In [36]: def func(y):
...: print(type(y))
...: return sum(x**(-y) for x in range(1, 10))
...: 在列表理解中,Python int被传递:
In [37]: func(3)
<class 'int'>
Out[37]: 1.1965319856741932使用vectorized版本:
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。
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,它就能工作:
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)的本质。
https://stackoverflow.com/questions/70595599
复制相似问题