且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

将2D数组复制到第3维,N次(Python)

更新时间:2023-11-27 13:59:10

可能最干净的方法是使用

Probably the cleanest way is to use np.repeat:

a = np.array([[1, 2], [1, 2]])
print(a.shape)
# (2,  2)

# indexing with np.newaxis inserts a new 3rd dimension, which we then repeat the
# array along, (you can achieve the same effect by indexing with None, see below)
b = np.repeat(a[:, :, np.newaxis], 3, axis=2)

print(b.shape)
# (2, 2, 3)

print(b[:, :, 0])
# [[1 2]
#  [1 2]]

print(b[:, :, 1])
# [[1 2]
#  [1 2]]

print(b[:, :, 2])
# [[1 2]
#  [1 2]]


话虽如此,通过使用广播.例如,假设我要添加一个(3,)向量:


Having said that, you can often avoid repeating your arrays altogether by using broadcasting. For example, let's say I wanted to add a (3,) vector:

c = np.array([1, 2, 3])

a.我可以在第三维中复制a的内容3次,然后在第一维和第二维中复制c的内容两次,这样我的两个数组都是(2, 2, 3),然后计算它们的总和.但是,这样做更加简单快捷:

to a. I could copy the contents of a 3 times in the third dimension, then copy the contents of c twice in both the first and second dimensions, so that both of my arrays were (2, 2, 3), then compute their sum. However, it's much simpler and quicker to do this:

d = a[..., None] + c[None, None, :]

在这里,a[..., None]具有形状(2, 2, 1),而c[None, None, :]具有形状(1, 1, 3) *.当我计算总和时,结果沿大小为1的维度广播"出去,结果为形状为(2, 2, 3):

Here, a[..., None] has shape (2, 2, 1) and c[None, None, :] has shape (1, 1, 3)*. When I compute the sum, the result gets 'broadcast' out along the dimensions of size 1, giving me a result of shape (2, 2, 3):

print(d.shape)
# (2,  2, 3)

print(d[..., 0])    # a + c[0]
# [[2 3]
#  [2 3]]

print(d[..., 1])    # a + c[1]
# [[3 4]
#  [3 4]]

print(d[..., 2])    # a + c[2]
# [[4 5]
#  [4 5]]

广播是一种非常强大的技术,因为它避免了在内存中创建输入数组的重复副本所涉及的额外开销.

Broadcasting is a very powerful technique because it avoids the additional overhead involved in creating repeated copies of your input arrays in memory.

*尽管为清楚起见我将它们包括在内,但实际上并不需要Nonec的索引-您也可以执行a[..., None] + c,即针对(3,)数组广播(2, 2, 1)数组.这是因为,如果其中一个数组的维数小于另一个数组的维数,则仅两个数组的 trailing 维度需要兼容.举一个更复杂的例子:

* Although I included them for clarity, the None indices into c aren't actually necessary - you could also do a[..., None] + c, i.e. broadcast a (2, 2, 1) array against a (3,) array. This is because if one of the arrays has fewer dimensions than the other then only the trailing dimensions of the two arrays need to be compatible. To give a more complicated example:

a = np.ones((6, 1, 4, 3, 1))  # 6 x 1 x 4 x 3 x 1
b = np.ones((5, 1, 3, 2))     #     5 x 1 x 3 x 2
result = a + b                # 6 x 5 x 4 x 3 x 2