2013-01-08 36 views
3

我具有值如何向量化一个1个dimensionsal阵列上的操作,以产生2维矩阵中numpy的

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. 

我正在寻找的结果是一个矩阵,它有两行,列数与输入数组一样多。为了达到这个目的,numpy中最好的符号是什么?

例如就等于

[1,2,3,4,5,6] 

和输出将等于

[[2,4,6,8,10,12], 
[3,6,9,12,15,18]] 
+0

您不应该使用'input'作为变量名称,您是否也可以显示预期输出的示例? – elyase

+0

添加了一个示例输出来显示结构。这些值是无关紧要的,可以用在fn内计算的任何值来代替 – bradgonesurfing

+0

您的函数和输出不匹配... – Jaime

回答

4

编辑 你应该尽量避免使用vectorize,因为它给的numpy的效率错觉,但里面是所有的python循环。

如果你真的需要处理用户提供的功能,它需要int秒并返回一个形状为(2, 1)matrix,那么你可能做得不多。但是这似乎是一个非常奇怪的用例。如果你能在需要的时候,即np.sin代替math.sin用的是采取int并返回int功能的列表,并使用ufuncs替换,你可以只是供大家参考执行以下操作

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的的ufuncs构造,你可以这样做np.vstack((a, f(a))),并得到你想要的东西

+0

没有,这只是一个退化的例子来显示原则。 fn内的转换可能是任何东西,但输出为(2,1)列矩阵 – bradgonesurfing

+0

@bradgonesurfing将其完全重新配置,基本想法仍然成立 – Jaime

+0

仍然没有好处。 f(a)返回一个列,每个列应该连接起来形成一个(2,N)矩阵。 fn可能是*任何东西* – bradgonesurfing

-1

矢量化的一个简单的重新实现给了我想要的东西

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

如果这不是高性能或有更好的方法,请让我知道。