bra*_*ing 4 numpy vectorization
我有一个值的数组
i = np.arange(0,7,1)
Run Code Online (Sandbox Code Playgroud)
和一个功能
# Returns a column matrix
def fn(i):
return np.matrix([[i*2,i*3]]).T
fnv = np.vectorize(fn)
Run Code Online (Sandbox Code Playgroud)
然后写作
fnv(i)
Run Code Online (Sandbox Code Playgroud)
给了我一个错误
File "<stdin>", line 1, in <module>
File "c:\Python33\lib\site-packages\numpy\lib\function_base.py",
line 1872, in __call__
return self._vectorize_call(func=func, args=vargs)
File "c:\Python33\lib\site-packages\numpy\lib\function_base.py",
line 1942, in _vectorize_call
copy=False, subok=True, dtype=otypes[0])
ValueError: setting an array element with a sequence.
Run Code Online (Sandbox Code Playgroud)
我要找的结果是一个矩阵,有两行,列数和输入数组一样多.实现这一点的numpy中最好的符号是什么?
例如,我会平等
[1,2,3,4,5,6]
Run Code Online (Sandbox Code Playgroud)
并且输出将相等
[[2,4,6,8,10,12],
[3,6,9,12,15,18]]
Run Code Online (Sandbox Code Playgroud)
编辑
你应该尽量避免使用vectorize,因为它给出了numpy效率的错觉,但在它内部的所有python循环.
如果你真的需要处理用户提供的带有ints并返回matrix形状的函数,(2, 1)那么你可能做的并不多.但这似乎是一个非常奇怪的用例.如果你可以用的是采取的函数列表替换int并返回int,并使用ufuncs在需要的时候,即np.sin代替math.sin,你可以做以下
def vectorize2(funcs) :
def fnv(arr) :
return np.vstack([f(arr) for f in funcs])
return fnv
f2 = vectorize2((lambda x : 2 * x, lambda x : 3 * x))
>>> f2(np.arange(10))
array([[ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18],
[ 0, 3, 6, 9, 12, 15, 18, 21, 24, 27]])
Run Code Online (Sandbox Code Playgroud)
仅供您参考,我已经将这个矢量化时间与你提出的一个:
f = vectorize(fn)
>>> timeit.timeit('f(np.arange(10))', 'from __main__ import np, f', number=1000)
0.28073329263679625
>>> timeit.timeit('f2(np.arange(10))', 'from __main__ import np, f2', number=1000)
0.023139129945661807
>>> timeit.timeit('f(np.arange(10000))', 'from __main__ import np, f', number=10)
2.3620706288432984
>>> timeit.timeit('f2(np.arange(10000))', 'from __main__ import np, f2', number=10)
0.002757072593169596
Run Code Online (Sandbox Code Playgroud)
因此,即使对于小型阵列,速度也有一个数量级,对于较大的阵列,它可以增长到x1000加速,几乎免费提供.
原始答案
vectorize除非没有办法,否则不要使用它,它很慢.请参阅以下示例
>>> a = np.array(range(7))
>>> a
array([0, 1, 2, 3, 4, 5, 6])
>>> np.vstack((a, a+1))
array([[0, 1, 2, 3, 4, 5, 6],
[1, 2, 3, 4, 5, 6, 7]])
>>> np.vstack((a, a**2))
array([[ 0, 1, 2, 3, 4, 5, 6],
[ 0, 1, 4, 9, 16, 25, 36]])
Run Code Online (Sandbox Code Playgroud)
无论你的功能是什么,如果它可以用numpy的ufuncs构建,你可以做类似的事情np.vstack((a, f(a)))并获得你想要的东西