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

时间:2020-12-26 21:42:50

I'm want to copy a numpy 2D array into a third dimension. For example, if I had such a (2D) numpy array:

我想把numpy 2D数组复制到第三维。例如,如果我有这样一个(2D) numpy数组:

import numpy as np
arr = np.array([[1,2],[1,2]])

convert it into a 3D matrix with N such copies in a new dimension, like this for N=3:

将它转换成一个3D矩阵,在一个新的维度中有N个这样的拷贝,比如N=3:

np.array([[[1,2],[1,2]],[[1,2],[1,2]],[[1,2],[1,2]]])

4 个解决方案

#1


50  

Probably the cleanest way is to use np.repeat:

可能最干净的方法是使用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]]

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:

话虽如此,您通常可以通过使用广播避免重复您的数组。例如,假设我想添加一个(3,)向量:

c = np.array([1, 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:

对于a,我可以在第三维中复制3次a的内容,然后在第一个维和第二个维中复制两次c的内容,这样我的两个数组都是(2,2,3),然后计算它们的和。然而,这样做要简单得多:

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

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):

在这里,一个[…, None]具有形状(2,2,1),c[None, None,:]具有形状(1,1,1,3)*。当我计算和时,结果会沿着尺寸1的维度“广播”出来,得到一个形状(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.

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


* 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:

*虽然我将它们包含在c中是为了明确,但实际上并不需要将None索引包含到c中——您还可以做一个[……],即对一个(3,)数组广播一个(2,2,1)数组。这是因为如果其中一个数组的维数比另一个数组少,那么两个数组的尾维数就必须是兼容的。举一个更复杂的例子:

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

#2


12  

Another way is to use numpy.dstack. Supposing that you want to repeat the matrix a num_repeats times:

另一种方法是使用numpy.dstack。假设你想要重复矩阵a num_repeat乘以:

import numpy as np
b = np.dstack([a]*num_repeats)

The trick is to wrap the matrix a into a list of a single element, then using the * operator to duplicate the elements in this list num_repeats times.

诀窍是将矩阵a封装到单个元素的列表中,然后使用*操作符复制这个列表中的元素num_repeat times。

For example, if:

例如,如果:

a = np.array([[1, 2], [1, 2]])
num_repeats = 5

This repeats the array of [1 2; 1 2] 5 times in the third dimension. To verify (in IPython):

这重复了[1 2]的数组;1 2]5次在第三维。验证(在IPython):

In [110]: import numpy as np

In [111]: num_repeats = 5

In [112]: a = np.array([[1, 2], [1, 2]])

In [113]: b = np.dstack([a]*num_repeats)

In [114]: b[:,:,0]
Out[114]: 
array([[1, 2],
       [1, 2]])

In [115]: b[:,:,1]
Out[115]: 
array([[1, 2],
       [1, 2]])

In [116]: b[:,:,2]
Out[116]: 
array([[1, 2],
       [1, 2]])

In [117]: b[:,:,3]
Out[117]: 
array([[1, 2],
       [1, 2]])

In [118]: b[:,:,4]
Out[118]: 
array([[1, 2],
       [1, 2]])

In [119]: b.shape
Out[119]: (2, 2, 5)

At the end we can see that the shape of the matrix is 2 x 2, with 5 slices in the third dimension.

在最后我们可以看到矩阵的形状是2×2,在第三维有5片。

#3


2  

A=np.array([[1,2],[3,4]])
B=np.asarray([A]*N)

Edit @Mr.F, to preserve dimension order:

编辑@Mr。F,保持尺寸顺序:

B=B.T

#4


1  

Here's a broadcasting example that does exactly what was requested.

这里有一个广播的例子,它完全符合要求。

a = np.array([[1, 2], [1, 2]])
a=a[:,:,None]
b=np.array([1]*5)[None,None,:]

Then b*a is the desired result and (b*a)[:,:,0] produces array([[1, 2],[1, 2]]), which is the original a, as does (b*a)[:,:,1], etc.

然后b*a是期望的结果,(b*a)[:, 0]产生数组([1,2],[1,2]),这是原始的a, as (b*a)[::,1]等。

#1


50  

Probably the cleanest way is to use np.repeat:

可能最干净的方法是使用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]]

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:

话虽如此,您通常可以通过使用广播避免重复您的数组。例如,假设我想添加一个(3,)向量:

c = np.array([1, 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:

对于a,我可以在第三维中复制3次a的内容,然后在第一个维和第二个维中复制两次c的内容,这样我的两个数组都是(2,2,3),然后计算它们的和。然而,这样做要简单得多:

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

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):

在这里,一个[…, None]具有形状(2,2,1),c[None, None,:]具有形状(1,1,1,3)*。当我计算和时,结果会沿着尺寸1的维度“广播”出来,得到一个形状(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.

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


* 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:

*虽然我将它们包含在c中是为了明确,但实际上并不需要将None索引包含到c中——您还可以做一个[……],即对一个(3,)数组广播一个(2,2,1)数组。这是因为如果其中一个数组的维数比另一个数组少,那么两个数组的尾维数就必须是兼容的。举一个更复杂的例子:

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

#2


12  

Another way is to use numpy.dstack. Supposing that you want to repeat the matrix a num_repeats times:

另一种方法是使用numpy.dstack。假设你想要重复矩阵a num_repeat乘以:

import numpy as np
b = np.dstack([a]*num_repeats)

The trick is to wrap the matrix a into a list of a single element, then using the * operator to duplicate the elements in this list num_repeats times.

诀窍是将矩阵a封装到单个元素的列表中,然后使用*操作符复制这个列表中的元素num_repeat times。

For example, if:

例如,如果:

a = np.array([[1, 2], [1, 2]])
num_repeats = 5

This repeats the array of [1 2; 1 2] 5 times in the third dimension. To verify (in IPython):

这重复了[1 2]的数组;1 2]5次在第三维。验证(在IPython):

In [110]: import numpy as np

In [111]: num_repeats = 5

In [112]: a = np.array([[1, 2], [1, 2]])

In [113]: b = np.dstack([a]*num_repeats)

In [114]: b[:,:,0]
Out[114]: 
array([[1, 2],
       [1, 2]])

In [115]: b[:,:,1]
Out[115]: 
array([[1, 2],
       [1, 2]])

In [116]: b[:,:,2]
Out[116]: 
array([[1, 2],
       [1, 2]])

In [117]: b[:,:,3]
Out[117]: 
array([[1, 2],
       [1, 2]])

In [118]: b[:,:,4]
Out[118]: 
array([[1, 2],
       [1, 2]])

In [119]: b.shape
Out[119]: (2, 2, 5)

At the end we can see that the shape of the matrix is 2 x 2, with 5 slices in the third dimension.

在最后我们可以看到矩阵的形状是2×2,在第三维有5片。

#3


2  

A=np.array([[1,2],[3,4]])
B=np.asarray([A]*N)

Edit @Mr.F, to preserve dimension order:

编辑@Mr。F,保持尺寸顺序:

B=B.T

#4


1  

Here's a broadcasting example that does exactly what was requested.

这里有一个广播的例子,它完全符合要求。

a = np.array([[1, 2], [1, 2]])
a=a[:,:,None]
b=np.array([1]*5)[None,None,:]

Then b*a is the desired result and (b*a)[:,:,0] produces array([[1, 2],[1, 2]]), which is the original a, as does (b*a)[:,:,1], etc.

然后b*a是期望的结果,(b*a)[:, 0]产生数组([1,2],[1,2]),这是原始的a, as (b*a)[::,1]等。