Using `numpy.vectorize` to create multidimensional array results in ValueError: setting an array element with a sequence
Using `numpy.vectorize` to create multidimensional array results in ValueError: setting an array element with a sequence
这个问题似乎只有在我的 dummy
函数 returns 一个数组时才会出现,因此,正在创建一个多维数组。
我将问题简化为以下示例:
def dummy(x):
y = np.array([np.sin(x), np.cos(x)])
return y
x = np.array([0, np.pi/2, np.pi])
我要优化的代码如下所示:
y = []
for x_i in x:
y_i = dummy(x_i)
y.append(y_i)
y = np.array(y)
所以我想,我可以使用 vectorize
摆脱慢循环:
y = np.vectorize(dummy)(x)
但这会导致
ValueError: setting an array element with a sequence.
错误所指的序列在哪里?!
我也不太明白这个错误,但是使用 python 3.6.3 你可以写:
y = dummy(x)
所以它是自动向量化的。
在官方documentation中也有这样写的:
The vectorize function is provided primarily for convenience, not for performance. The implementation is essentially a for loop.
我希望这至少能有所帮助。
你的函数 returns 给定标量时的数组:
In [233]: def dummy(x):
...: y = np.array([np.sin(x), np.cos(x)])
...: return y
...:
...:
In [234]: dummy(1)
Out[234]: array([0.84147098, 0.54030231])
In [235]: f = np.vectorize(dummy)
In [236]: f([0,1,2])
...
ValueError: setting an array element with a sequence.
vectorize
构造一个空的结果数组,并尝试将每次计算的结果放入其中。但是目标数组的单元格不能接受数组。
如果我们指定 otypes
参数,它确实有效:
In [237]: f = np.vectorize(dummy, otypes=[object])
In [238]: f([0,1,2])
Out[238]:
array([array([0., 1.]), array([0.84147098, 0.54030231]),
array([ 0.90929743, -0.41614684])], dtype=object)
即每个dummy
数组放入一个形状为(3,)结果数组的元素中。
由于组件数组都具有相同的形状,我们可以stack
它们:
In [239]: np.stack(_)
Out[239]:
array([[ 0. , 1. ],
[ 0.84147098, 0.54030231],
[ 0.90929743, -0.41614684]])
但如前所述,vectorize
不保证加速。我怀疑我们也可以使用较新的 signature
参数,但那会更慢。
vectorize
如果您的函数采用多个标量参数,并且您希望在提供值集时利用 numpy 广播,则有些意义。但是作为对一维数组的简单迭代的替代,它并不是一个改进。
这个问题似乎只有在我的 dummy
函数 returns 一个数组时才会出现,因此,正在创建一个多维数组。
我将问题简化为以下示例:
def dummy(x):
y = np.array([np.sin(x), np.cos(x)])
return y
x = np.array([0, np.pi/2, np.pi])
我要优化的代码如下所示:
y = []
for x_i in x:
y_i = dummy(x_i)
y.append(y_i)
y = np.array(y)
所以我想,我可以使用 vectorize
摆脱慢循环:
y = np.vectorize(dummy)(x)
但这会导致
ValueError: setting an array element with a sequence.
错误所指的序列在哪里?!
我也不太明白这个错误,但是使用 python 3.6.3 你可以写:
y = dummy(x)
所以它是自动向量化的。
在官方documentation中也有这样写的:
The vectorize function is provided primarily for convenience, not for performance. The implementation is essentially a for loop.
我希望这至少能有所帮助。
你的函数 returns 给定标量时的数组:
In [233]: def dummy(x):
...: y = np.array([np.sin(x), np.cos(x)])
...: return y
...:
...:
In [234]: dummy(1)
Out[234]: array([0.84147098, 0.54030231])
In [235]: f = np.vectorize(dummy)
In [236]: f([0,1,2])
...
ValueError: setting an array element with a sequence.
vectorize
构造一个空的结果数组,并尝试将每次计算的结果放入其中。但是目标数组的单元格不能接受数组。
如果我们指定 otypes
参数,它确实有效:
In [237]: f = np.vectorize(dummy, otypes=[object])
In [238]: f([0,1,2])
Out[238]:
array([array([0., 1.]), array([0.84147098, 0.54030231]),
array([ 0.90929743, -0.41614684])], dtype=object)
即每个dummy
数组放入一个形状为(3,)结果数组的元素中。
由于组件数组都具有相同的形状,我们可以stack
它们:
In [239]: np.stack(_)
Out[239]:
array([[ 0. , 1. ],
[ 0.84147098, 0.54030231],
[ 0.90929743, -0.41614684]])
但如前所述,vectorize
不保证加速。我怀疑我们也可以使用较新的 signature
参数,但那会更慢。
vectorize
如果您的函数采用多个标量参数,并且您希望在提供值集时利用 numpy 广播,则有些意义。但是作为对一维数组的简单迭代的替代,它并不是一个改进。