如何将一维数组上的操作矢量化以生成numpy中的二维矩阵

如何将一维数组上的操作矢量化以生成numpy中的二维矩阵,numpy,vectorization,Numpy,Vectorization,我有一个1d值数组 i = np.arange(0,7,1) 和一个函数 # Returns a column matrix def fn(i): return np.matrix([[i*2,i*3]]).T fnv = np.vectorize(fn) 然后写 fnv(i) 给我一个错误 File "<stdin>", line 1, in <module> File "c:\Python33\lib\site-packages\numpy

我有一个1d值数组

i = np.arange(0,7,1)
和一个函数

# Returns a column matrix
def fn(i):
    return np.matrix([[i*2,i*3]]).T


fnv = np.vectorize(fn) 
然后写

fnv(i)
给我一个错误

  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.
产量将相等

[[2,4,6,8,10,12],
 [3,6,9,12,15,18]]
编辑 您应该尽量避免使用
vectorize
,因为它给人一种numpy效率的错觉,但在它的内部是所有python循环

如果您真的必须处理用户提供的函数,这些函数采用
int
s并返回一个
矩阵
(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]])
仅供参考,我已将此矢量化与您建议的矢量化进行了比较:

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
因此,即使是小型阵列,其速度也有一个数量级,可以提高到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]])

不管你的函数是什么,如果它可以用numpy的UFUNC构造,你可以做一些类似于
np.vstack((a,f(a))
的事情,得到你想要的

def vectorize( fn):
    def do_it (array):
        return np.column_stack((fn(p) for p in array))
    return do_it

如果没有性能,或者有更好的方法,请告诉我。

您不应该使用“输入”作为变量名,也可以显示预期输出的示例吗?添加示例输出只是为了显示结构。这些值是不相关的,可以用函数中计算的任何值替换,并且输出不匹配…是的,它匹配。f(1)->[2,3]'f(2)->[4,6]'ETC这么复杂?生成一系列列,并以最快的方式将它们连接在一起,生成一个matrixNo,这只是一个演示原理的退化示例。fn中的转换可以是任何东西,但不能作为(2,1)列输出matrix@bradgonesurfing彻底重述它,基本思想仍然坚持到不行。f(a)返回一列,每个列都应该连接起来形成一个(2,N)矩阵。fn可以是任何澄清UFUNC的银行。作为一个老的Matlab黑客,我应该知道寻找这种东西。
def vectorize( fn):
    def do_it (array):
        return np.column_stack((fn(p) for p in array))
    return do_it