矢量化函数无法评估
Vectorized function fails to evaluate
我在使用矢量化函数时遇到问题:
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
处理此示例?
当函数在 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
整数。
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
。但是对于列表或可以压缩的列表,它不会增加列表理解的任何内容——甚至速度也不行。
如本案例所示,它有一些新手(甚至更有经验的用户)无法捕捉到的陷阱。这是输入的性质。对于许多其他 SO 问题,它是 return 值的性质(自动 otypes
)。
我在使用矢量化函数时遇到问题:
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
处理此示例?
当函数在 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
整数。
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
。但是对于列表或可以压缩的列表,它不会增加列表理解的任何内容——甚至速度也不行。
如本案例所示,它有一些新手(甚至更有经验的用户)无法捕捉到的陷阱。这是输入的性质。对于许多其他 SO 问题,它是 return 值的性质(自动 otypes
)。