Python Numpy:将三个1D阵列组装成3D(但不完全是一个简单的坐标网格)
我有三个一维数组,其中两个长度相同,但第三个长度不同,例如Python Numpy:将三个1D阵列组装成3D(但不完全是一个简单的坐标网格),python,numpy,Python,Numpy,我有三个一维数组,其中两个长度相同,但第三个长度不同,例如 A = np.array([1, 2, 3, 4]) B = np.array([10, 20, 30, 40]) C = np.array([100, 200, 300, 400, 500]) 我想将它们组合成一个网格,如下所示: D = np.array([[[1, 10, 100], [1, 10, 200], [1, 10, 300], [1, 10, 400], [1, 10, 500]], [[
A = np.array([1, 2, 3, 4])
B = np.array([10, 20, 30, 40])
C = np.array([100, 200, 300, 400, 500])
我想将它们组合成一个网格,如下所示:
D = np.array([[[1, 10, 100], [1, 10, 200], [1, 10, 300], [1, 10, 400], [1, 10, 500]],
[[2, 20, 100], [2, 20, 200], [2, 20, 300], [2, 20, 400], [2, 20, 500]],
[[3, 30, 100], [3, 30, 200], [3, 30, 300], [3, 30, 400], [3, 30, 500]],
[[4, 40, 100], [4, 40, 200], [4, 40, 300], [4, 40, 400], [4, 40, 500]]])
它类似于坐标网格,但是a
和B
一起变化,所以我假设它们需要先组合,然后生成的2D数组以某种方式与C组合,但是我找不到堆栈
,串联
,网格
等的正确组合
实际数组将比这个示例大得多(每个数组有数千个值),并且代码将被调用很多次,因此速度非常重要。它将位于MCMC采样器的主回路中,其中A
和B
是每个回路上变化的参数,而C
是一个常数。
让我们分别调用
A
,B
,C
A
,B
,C
。您正在查找形状(a,c,3)
(或(b,c,3)
)的输出数组。正确地堆叠A
和B
将为您提供一组形状(A,2)
:
为了能够将C
附加到zipped
,您需要沿结果的前两个轴将数组广播为相同的形状:
Aa = np.broadcast_to(zipped[..., None, :], (A.size, C.size, 2))
Cc = np.broadcast_to(C[..., None], (A.size, C.size, 1))
result = np.append(Aa, Cc, axis=-1)
整个操作可以写成一行:
result = np.append(np.broadcast_to(np.stack((A, B), axis=-1)[..., None, :], (A.size, C.size, 2)), np.broadcast_to(C[..., None], (A.size, C.size, 1)), axis=-1)
此操作相当有效:
np.broadcast\u to
创建视图而不复制任何数据。只有append
操作本身才进行复制。您可以利用不同方向矩阵的乘法,然后进行串联,以获得所需的结果:
A = np.array([1,2,3,4]).reshape((4,1,1))
B = np.array([10,20,30,40]).reshape((4,1,1))
C = np.array([100,200,300,400,500]).reshape((1,5,1))
res = np.concatenate([A*np.ones((1,5,1)),B*np.ones((1,5,1)),C*np.ones((4,1,1))],axis=2)
print(res)
收益率:
res
这种类型的操作非常快,但如果矩阵非常大,则可能会遇到性能问题。此操作需要占用大量内存。每次应该有4列,对吗?所有列都应该是相同的吗?不,唯一的常量是有三个输入数组,C的值在循环之间不会改变
result = np.append(np.broadcast_to(np.stack((A, B), axis=-1)[..., None, :], (A.size, C.size, 2)), np.broadcast_to(C[..., None], (A.size, C.size, 1)), axis=-1)
A = np.array([1,2,3,4]).reshape((4,1,1))
B = np.array([10,20,30,40]).reshape((4,1,1))
C = np.array([100,200,300,400,500]).reshape((1,5,1))
res = np.concatenate([A*np.ones((1,5,1)),B*np.ones((1,5,1)),C*np.ones((4,1,1))],axis=2)
print(res)
Out[152]:
array([[[ 1., 10., 100.],
[ 1., 10., 200.],
[ 1., 10., 300.],
[ 1., 10., 400.],
[ 1., 10., 500.]],
[[ 2., 20., 100.],
[ 2., 20., 200.],
[ 2., 20., 300.],
[ 2., 20., 400.],
[ 2., 20., 500.]],
[[ 3., 30., 100.],
[ 3., 30., 200.],
[ 3., 30., 300.],
[ 3., 30., 400.],
[ 3., 30., 500.]],
[[ 4., 40., 100.],
[ 4., 40., 200.],
[ 4., 40., 300.],
[ 4., 40., 400.],
[ 4., 40., 500.]]])