如何使用另一个数组创建或填充numpy数组?

5
如何创建一个形状为[2, 2, 3]的 numpy 数组,在第二维的元素是另一个数组,例如[1, 2, 3]
我想做类似于下面这个无效代码的操作:
a = np.arange(1, 4)
b = np.full((3, 3), a)

导致类似以下数组的结果:
[[[ 1.  2.  3.]
  [ 1.  2.  3.]]
 [[ 1.  2.  3.]
  [ 1.  2.  3.]]]

当然可以像往常一样编写填充的循环,但我认为可能有一种捷径:

for y in range(b.shape[0]):
    for x in range(b.shape[1]):
        b[y, x, :] = a

3
使用np.full函数和期望的形状即可:np.full((2,2,3), a)。 - Divakar
“其中轴 2 上的元素是另一个数组。” 那应该是一个 (2,3) 形状的数组,对吧?你建议的 [1,2,3] 不是... - Tom de Geus
@TomdeGeus:不,这个例子的意图是创建一个形状为[2, 2, 3]的数组,或者我称之为[2, 2]数组,其中元素是一个[3]数组。 - EquipDev
@Divakar:谢谢,解决了。 - EquipDev
如果数组是对象类型,则 full 可能会产生意外的结果,http://stackoverflow.com/q/43483663。在这种情况下,它的行为类似于 [[]]*4 - hpaulj
4个回答

3

有多种方法可以实现这一点。其中一种是使用Divakar在评论中指出的np.full((2,2,3), a)中的np.full。或者,您可以使用np.tile来构建一个数组,通过重复输入数组给定次数来实现。要构建您的示例,您可以执行以下操作:

import numpy as np

np.tile(np.arange(1, 4), [2, 2, 1])

2
如果您的numpy版本大于等于1.10,您可以使用broadcast_to函数。
a = np.arange(1,4)
a.shape = (1,1,3)
b = np.broadcast_to(a,(2,2,3))

这将生成一个视图而不是复制,因此对于大型数组来说会更快。

编辑:这似乎是您在演示中要求的结果。


输出的数组与要求相同,但我认为语法不如jotasi和Divakar的答案明显且易于记忆。 - EquipDev
同意。在某种程度上!如果a的维度小于输出结果(broadcast_to实际上也是如此),tile()会自动添加一些轴,因此我加入了reshape行以展示如何控制该过程。你可以认为将其广播到结果数组的形状更清晰。正如我所提到的,broadcast_to的优点在于它创建了一个只读视图,因此非常快速。 - paddyg

2
基于Divakar的评论,另一个答案可以是:
import numpy as np
np.full([2, 2, 3], np.arange(1, 4))

另一种可能性是:
import numpy as np
b = np.empty([2, 2, 3])
b[:] = np.arange(1, 4)

1
此外还可以使用 np.concatenate 或其包装器 np.vstack
In [26]: a = np.arange(1,4)

In [27]: np.vstack([a[np.newaxis, :]]*4).reshape(2,2, 3)
Out[27]: 
array([[[1, 2, 3],
        [1, 2, 3]],

       [[1, 2, 3],
        [1, 2, 3]]])

In [28]: np.concatenate([a[np.newaxis, :]]*4, axis=0).reshape(2,2, 3)
Out[28]: 
array([[[1, 2, 3],
        [1, 2, 3]],

       [[1, 2, 3],
        [1, 2, 3]]])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接