我想创建一个输入为x.shape==(2,2)
的函数,并输出y.shape==(2,2,3)
。
例如:
@np.vectorize
def foo(x):
#This function doesn't work like I want
return x,x,x
a = np.array([[1,2],[3,4]])
print(foo(a))
#desired output
[[[1 1 1]
[2 2 2]]
[[3 3 3]
[4 4 4]]]
#actual output
(array([[1, 2],
[3, 4]]), array([[1, 2],
[3, 4]]), array([[1, 2],
[3, 4]]))
或者也许:
@np.vectorize
def bar(x):
#This function doesn't work like I want
return np.array([x,2*x,5])
a = np.array([[1,2],[3,4]])
print(bar(a))
#desired output
[[[1 2 5]
[2 4 5]]
[[3 6 5]
[4 8 5]]]
请注意foo
只是一个例子。我想要一个方法map
超过一个numpy数组(这是vectorize应该做的),但让map
获取一个0d对象并在其位置推送一个1d对象。在我看来,这里的维度是任意的,因为人们可能希望采用一个函数来获取1d对象并返回一个3d对象,对其进行矢量化,在5d对象上调用它,然后返回一个7d对象......但是,我的特定用例只需要向量化0d到1d函数,并在2d数组上正确映射它。
答案 0 :(得分:2)
将值重复到另一个维度非常简单:
import numpy as np
x = a = np.array([[1,2],[3,4]])
y = np.repeat(x[:,:,np.newaxis], 3, axis=2)
print y.shape
print y
(2L, 2L, 3L)
[[[1 1 1]
[2 2 2]]
[[3 3 3]
[4 4 4]]]
答案 1 :(得分:2)
在您的问题中,显示实际结果和您想要的结果会有所帮助。正如所写,不是很清楚。
In [79]: foo(np.array([[1,2],[3,4]]))
Out[79]:
(array([[1, 2],
[3, 4]]), array([[1, 2],
[3, 4]]), array([[1, 2],
[3, 4]]))
如vectorize
文档中所示,这返回了一个数组元组,对应于函数返回的元组值。
您的bar
会返回一个数组,其中vectorize
期望它返回一个标量(或单个值):
In [82]: bar(np.array([[1,2],[3,4]]))
ValueError: setting an array element with a sequence.
vectorize
采用有时有帮助的otypes
参数。例如,如果我说bar
(没有包装器)返回一个对象,我得到:
In [84]: f=np.vectorize(bar, otypes=[object])
In [85]: f(np.array([[1,2],[3,4]]))
Out[85]:
array([[array([1, 2, 5]), array([2, 4, 5])],
[array([3, 6, 5]), array([4, 8, 5])]], dtype=object)
(3)数组的(2,2)数组。 (2,2)
形状与输入的形状相匹配。
vectorize
有一个相对较新的参数signature
In [90]: f=np.vectorize(bar, signature='()->(n)')
In [91]: f(np.array([[1,2],[3,4]]))
Out[91]:
array([[[1, 2, 5],
[2, 4, 5]],
[[3, 6, 5],
[4, 8, 5]]])
In [92]: _.shape
Out[92]: (2, 2, 3)
我还没有使用过这么多,所以我仍然对它的运作方式有所了解。当我测试它时,它比vectorize
的原始标量版本慢。两者都没有提供显式循环的任何速度优势。但是,vectorize
在广播时会有所帮助,允许您使用各种输入形状。当你的函数接受多个输入时,这更有用,而不仅仅是一个输入。
In [94]: f(np.array([1,2]))
Out[94]:
array([[1, 2, 5],
[2, 4, 5]])
In [95]: f(np.array(3))
Out[95]: array([3, 6, 5])
为了获得最佳速度,您希望尽可能使用现有的numpy全数组函数。例如,您的foo
案例可以通过以下方式完成:
In [97]: np.repeat(a[:,:,None],3, axis=2)
Out[97]:
array([[[1, 1, 1],
[2, 2, 2]],
[[3, 3, 3],
[4, 4, 4]]])
np.stack([a]*3, axis=2)
也有效。
您的bar
期望结果:
In [100]: np.stack([a, 2*a, np.full(a.shape, 5)], axis=2)
Out[100]:
array([[[1, 2, 5],
[2, 4, 5]],
[[3, 6, 5],
[4, 8, 5]]])
2*a
利用了整数组乘法。这是真正的&numpy-onic'思。
答案 2 :(得分:0)
这似乎适用于" f R0 - > R1映射到nd数组,给出(n + 1)d one"
def foo(x):
return np.concatenate((x,x))
np.apply_along_axis(foo,2,x.reshape(list(x.shape)+[1]))
尽管,并没有很好地概括这一切