对返回向量的函数使用Numpy矢量化

2024-05-14 08:23:01 发布

您现在位置:Python中文网/ 问答频道 /正文

numpy.vectorize接受一个函数f:a->;b并将其转换为g:a[]->;b[]。

ab是标量时,这很好,但我想不出为什么它不能与b一起作为ndarray或列表工作,即f:a-&g t;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))

这将产生:

array([[ 0.  0.  0.  0.  0.],
       [ 1.  1.  1.  1.  1.],
       [ 2.  2.  2.  2.  2.],
       [ 3.  3.  3.  3.  3.]], dtype=object)

好的,这样就给出了正确的值,但是错误的数据类型。更糟的是:

g(a).shape

收益率:

(4,)

所以这个数组几乎没用。我知道我可以改变它:

np.array(map(list, a), dtype=np.float32)

给我想要的:

array([[ 0.,  0.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 2.,  2.,  2.,  2.,  2.],
       [ 3.,  3.,  3.,  3.,  3.]], dtype=float32)

但这既不是有效的,也不是Python。你们能找个更干净的方法吗?

提前谢谢!


Tags: 函数importgtnumpy列表returndefas
3条回答

np.vectorize只是一个方便的函数。它实际上不是make code run any faster。如果不方便使用np.vectorize,只需编写自己的函数即可。

np.vectorize的目的是将不知道numpy的函数(例如,将float作为输入,将float作为输出)转换为可以操作(和返回)numpy数组的函数。

您的函数f已经知道numpy——它在定义中使用numpy数组并返回numpy数组。因此np.vectorize不适合您的用例。

因此,解决的办法就是按你所希望的方式运行你自己的函数f

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)

这应该可以解决问题,而且无论您的输入大小如何,都可以正常工作。”map“只适用于一维输入。使用“.tolist()”并创建一个新的ndarray可以更彻底、更完美地解决问题(我相信)。希望这有帮助。

在1.12.0中有一个新的参数signature做的正是您所做的。

def f(x):
    return x * np.array([1,1,1,1,1], dtype=np.float32)

g = np.vectorize(f, signature='()->(n)')

然后g(np.arange(4)).shape将给出(4L, 5L)

这里指定了f的签名。(n)是返回值的形状,()是标量参数的形状。参数也可以是数组。有关更复杂的签名,请参见Generalized Universal Function API

相关问题 更多 >

    热门问题