为什么np.vvectorize(max)不能按预期工作



我有以下代码

import numpy as np
f = np.vectorize(lambda x: max(x, 0))
print(f(-0.3))
print(f(1.8))
print(f([1.8, -0.3]))
print(f([-0.3, 1.8]))

我有输出:

0
1.8
[1.8 0. ]
[0 1]

有人能解释为什么f([-0.3,1.8](得到[01]吗

我只是做另一个测试:

print(type(f([3])[0]))
print(f([3, 1.5]))

现在我得到

<class 'numpy.int32'>
[3.  1.5]

如果矢量化的输出的数据类型是通过调用具有输入的第一个元素的函数来确定的。为什么第二种情况如预期一样有效?

在不阅读完整文档的情况下使用np.vectorize是危险的,或者至少是令人讨厌的。

返回的数据类型由第一个测试用例确定:

In [52]: np.vectorize(lambda x: max(x,0))(np.linspace(-1,1,6))
Out[52]: array([0, 0, 0, 0, 0, 1])

注意整数值。带有浮点值:

In [53]: np.vectorize(lambda x: max(x,0.0))(np.linspace(-1,1,6))
Out[53]: array([0. , 0. , 0. , 0.2, 0.6, 1. ])

或者明确设置:

In [54]: np.vectorize(lambda x: max(x,0),otypes=['f'])(np.linspace(-1,1,6))
Out[54]: array([0. , 0. , 0. , 0.2, 0.6, 1. ], dtype=float32)

但对于这样的函数,请完全跳过vectorize

In [55]: np.maximum(np.linspace(-1,1,6),0)
Out[55]: array([0. , 0. , 0. , 0.2, 0.6, 1. ])

列表理解通常和vectorize:一样好

In [56]: np.array([max(x,0) for x in np.linspace(-1,1,6)])
Out[56]: array([0. , 0. , 0. , 0.2, 0.6, 1. ])

时间测试通常表明,在大多数情况下,列表理解速度更快。当前版本的vectorize对于非常大的阵列确实具有适度的速度优势。但是适当的";矢量化的";版本,如[55]中所述,最适合所有尺寸。

vectorize通常与涉及if/else子句的函数一起使用,因为它们只适用于标量值。为其中一种情况返回整数值是一个常见的错误。

In [57]: def foo(x):
...:     if x<0:
...:         return 0
...:     else:
...:         return x
...: 
In [58]: np.vectorize(foo)(np.linspace(-1,1,6))
Out[58]: array([0, 0, 0, 0, 0, 1])

如文档中所述:

vectorized输出的数据类型通过调用函数的第一个元素。这可以通过以下方式避免指定CCD_ 8参数。

因此,由于第一个的输出是int对象,因此它推断numpy.int64为输出dtype。

不过,更重要的是,您可能不应该在这里使用numpy.vectorize,它实际上没有任何意义。如果我可以问的话,你为什么要用它?请记住文档的另一个重要部分:

提供矢量化函数主要是为了方便,而不是表演该实现本质上是一个for循环。

不确定确切的原因,但我认为矢量化在区分数据类型方面并不太聪明。更改";0";至";0.0";你可能会得到更好的结果。

最新更新