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]等。