In [145]: def f(string):
...: print('called with', string)
...:
...: a = np.array(['110', '012'])
...:
...: fv = np.vectorize(f)
...:
In [146]: fv(a)
called with 110
called with 110
called with 012
Out[146]: array([None, None], dtype=object)
只有一个print的函数返回
None
.
vectorized
调用它一次以确定返回的数据类型-在本例中,它推断
object
.
如果我们指定
otypes
喜欢
int
,我们得到一个错误:
In [147]: fv = np.vectorize(f, otypes=[int])
In [148]: fv(a)
called with 110
called with 012
---------------------------------------------------------------------------
...
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
那
类型
与返回的对象不兼容
In [149]: fv = np.vectorize(f, otypes=[object])
In [150]: fv(a)
called with 110
called with 012
Out[150]: array([None, None], dtype=object)
一个更好、更有意义的功能:
In [151]: def f(string):
...: print('called with', string)
...: return len(string)
...:
...:
In [152]: fv = np.vectorize(f, otypes=[int])
In [153]: fv(a)
called with 110
called with 012
Out[153]: array([3, 3])
记住
vectorize
将标量值传递给函数。实际上,它评估输入数组的每个元素,返回具有匹配形状的数组:
In [154]: fv(np.array([a,a,a]))
called with 110
called with 012
called with 110
called with 012
called with 110
called with 012
Out[154]:
array([[3, 3],
[3, 3],
[3, 3]])
与普通迭代相比,例如
np.array([f(i) for i in a])
,速度较慢,但如果输入数组可以具有多个维度,则稍微方便一点,如果有多个数组需要相互广播,则更好。
对于一个简单的单数组
a
,
np.vectorize
是多余的。
矢量化
有另一个参数,
cache
它可以避免这种双重调用,同时还允许自动检测数据类型:
In [156]: fv = np.vectorize(f, cache=True)
In [157]: fv(a)
called with 110
called with 012
Out[157]: array([3, 3])
自动数据类型检测有时会导致错误。例如,如果试用计算返回不同的数据类型:
In [160]: def foo(var):
...: if var<0:
...: return -var
...: elif var>0:
...: return var
...: else:
...: return 0
In [161]: np.vectorize(foo)([0,1.2, -1.2])
Out[161]: array([0, 1, 1]) # int dtype
In [162]: np.vectorize(foo)([0.1,1.2, -1.2])
Out[162]: array([0.1, 1.2, 1.2]) # float dtype
apply_along_axis
接受接受一维数组的函数。它迭代所有其他维度,向函数传递一组一维切片。对于像你的
一
这没用。即使你的
一
是的,不会有多大帮助。你的
fv
不需要1d输入。
它还进行了一次尝试计算,以确定返回数组的形状和数据类型。它会自动缓存结果。
喜欢
矢量化
,
沿轴应用
是一个方便的工具,而不是性能工具。
比较
np.apply_along_axis(fv, axis=0, arr=[a,a,a])
np.apply_along_axis(fv, axis=1, arr=[a,a,a])
了解如何
apply_along
影响评估顺序。
或者做一些整体的事情
row
(或列)具有:
np.apply_along_axis(lambda x: fv(x).mean(), axis=0, arr=[a,a,a])