我需要从一维数组和标量列表创建2D numpy数组,以便复制标量以匹配一维数组的长度.
期望行为的例子
>>> x = np.ones(5)
>>> something([x, 0, x])
array([[ 1., 1., 1., 1., 1.],
[ 0., 0., 0., 0., 0.],
[ 1., 1., 1., 1., 1.]])
我知道列表中的矢量元素将总是具有相同的长度(形状),因此我可以通过执行以下操作来“手工”完成:
def something(lst):
for e in lst:
if isinstance(e, np.ndarray):
l = len(e)
break
tmp = []
for e in lst:
if isinstance(e, np.ndarray):
tmp.append(e)
l = len(e)
else:
tmp.append(np.empty(l))
tmp[-1][:] = e
return np.array(tmp)
我要问的是在numpy中某个地方是否隐藏了一些现成的解决方案,或者如果没有,那么是否有比上述解决方案更好(例如,更通用,更可靠,更快)的解决方案.
解决方法:
In [179]: np.column_stack(np.broadcast(x, 0, x))
Out[179]:
array([[ 1., 1., 1., 1., 1.],
[ 0., 0., 0., 0., 0.],
[ 1., 1., 1., 1., 1.]])
要么
In [187]: np.row_stack(np.broadcast_arrays(x, 0, x))
Out[187]:
array([[ 1., 1., 1., 1., 1.],
[ 0., 0., 0., 0., 0.],
[ 1., 1., 1., 1., 1.]])
使用np.broadcast比np.broadcast_arrays更快:
In [195]: %timeit np.column_stack(np.broadcast(*[x, 0, x]*10))
10000 loops, best of 3: 46.4 µs per loop
In [196]: %timeit np.row_stack(np.broadcast_arrays(*[x, 0, x]*10))
1000 loops, best of 3: 380 µs per loop
但比你的something函数慢:
In [201]: %timeit something([x, 0, x]*10)
10000 loops, best of 3: 37.3 µs per loop
请注意,np.broadcast最多可以传递32个数组:
In [199]: np.column_stack(np.broadcast(*[x, 0, x]*100))
ValueError: Need at least two and fewer than (32) array objects.
而np.broadcast_arrays是无限的:
In [198]: np.row_stack(np.broadcast_arrays(*[x, 0, x]*100))
Out[198]:
array([[ 1., 1., 1., 1., 1.],
[ 0., 0., 0., 0., 0.],
[ 1., 1., 1., 1., 1.],
...,
[ 1., 1., 1., 1., 1.],
[ 0., 0., 0., 0., 0.],
[ 1., 1., 1., 1., 1.]])
使用np.broadcast或np.broadcast_arrays比
的东西.它将适用于不同(但可广播)形状的阵列,
实例:
In [209]: np.column_stack(np.broadcast(*[np.atleast_2d(x), 0, x]))
Out[209]:
array([[ 1., 1., 1., 1., 1.],
[ 0., 0., 0., 0., 0.],
[ 1., 1., 1., 1., 1.]])
而something([np.atleast_2d(x),0,x])返回:
In [211]: something([np.atleast_2d(x), 0, x])
Out[211]:
array([array([[ 1., 1., 1., 1., 1.]]), array([ 0.]),
array([ 1., 1., 1., 1., 1.])], dtype=object)