pro*_*ius 31 python arrays numpy vectorization
numpy.vectorize
取函数f:a-> b并将其变为g:a [] - > b [].
这在标量a
和b
标量时都可以正常工作,但是我想不出为什么它不能用b作为ndarray
或列表,即f:a-> b []和g:a [] - > b [] []
例如:
import numpy as np
def f(x):
return x * np.array([1,1,1,1,1], dtype=np.float32)
g = np.vectorize(f, otypes=[np.ndarray])
a = np.arange(4)
print(g(a))
Run Code Online (Sandbox Code Playgroud)
这会产生:
array([[ 0. 0. 0. 0. 0.],
[ 1. 1. 1. 1. 1.],
[ 2. 2. 2. 2. 2.],
[ 3. 3. 3. 3. 3.]], dtype=object)
Run Code Online (Sandbox Code Playgroud)
好的,所以给出了正确的值,但错误的dtype.更糟糕的是:
g(a).shape
Run Code Online (Sandbox Code Playgroud)
收益率:
(4,)
Run Code Online (Sandbox Code Playgroud)
所以这个阵列几乎没用.我知道我可以将其转换为:
np.array(map(list, a), dtype=np.float32)
Run Code Online (Sandbox Code Playgroud)
给我我想要的东西:
array([[ 0., 0., 0., 0., 0.],
[ 1., 1., 1., 1., 1.],
[ 2., 2., 2., 2., 2.],
[ 3., 3., 3., 3., 3.]], dtype=float32)
Run Code Online (Sandbox Code Playgroud)
但这既不高效也不高潮.你们中的任何人都能找到更清洁的方法吗?
提前致谢!
unu*_*tbu 40
np.vectorize
只是一个便利功能.它实际上并没有使代码运行得更快.如果使用起来不方便np.vectorize
,只需编写自己的功能即可.
目的np.vectorize
是转换不是numpy-aware的函数(例如将float作为输入并将float作为输出返回)到可以操作(并返回)numpy数组的函数中.
你的函数f
已经是numpy-aware - 它在其定义中使用了一个numpy数组并返回一个numpy数组.因此np.vectorize
不适合您的用例.
因此,解决方案就是按照您f
的方式运行您自己的功能.
Cos*_*syn 10
signature
1.12.0中的新参数完全符合您的要求.
def f(x):
return x * np.array([1,1,1,1,1], dtype=np.float32)
g = np.vectorize(f, signature='()->(n)')
Run Code Online (Sandbox Code Playgroud)
然后g(np.arange(4)).shape
会给(4L, 5L)
.
这里f
指定了签名.它(n)
是返回值()
的形状,是标量参数的形状.参数也可以是数组.有关更复杂的签名,请参阅通用通用函数API.
小智 5
import numpy as np
def f(x):
return x * np.array([1,1,1,1,1], dtype=np.float32)
g = np.vectorize(f, otypes=[np.ndarray])
a = np.arange(4)
b = g(a)
b = np.array(b.tolist())
print(b)#b.shape = (4,5)
c = np.ones((2,3,4))
d = g(c)
d = np.array(d.tolist())
print(d)#d.shape = (2,3,4,5)
Run Code Online (Sandbox Code Playgroud)
这应该可以解决该问题,并且无论输入大小如何,它都可以工作。“地图”仅适用于一个三维输入。使用“ .tolist()”并创建一个新的ndarray可以更完全,更好地解决该问题(我相信)。希望这可以帮助。