Numpy:将三个1D阵列组装成3D(但不完全是一个简单的坐标网格)

2024-05-31 23:39:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我有三个一维数组,其中两个长度相同,但第三个长度不同,例如

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

它类似于坐标网格,但其中AB一起变化,因此我假设它们需要先组合,然后生成的2D数组以某种方式与C组合,但我找不到stackconcatenatemeshgrid等的正确组合

实际数组将比这个示例大得多(每个数组有数千个值),并且代码将被调用很多次,因此速度非常重要。它将位于MCMC采样器的主循环中,其中AB是每个循环上变化的参数,而C是一个常量


Tags: 代码网格示例参数stacknp方式数组
3条回答

让我们分别调用ABC{}、bc的长度。您正在寻找形状为(a, c, 3)(或(b, c, 3))的输出数组。正确地堆叠AB将为您提供一个形状数组(a, 2)

zipped = np.stack((A, B), axis=-1)

为了能够将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_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

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.]]])

这种类型的操作非常快,但如果矩阵非常大,则可能会遇到性能问题。此操作确实需要使用大量内存

column_stack

A = np.array([1,2,3,4])
B = np.array([10,20,30,40])
C = np.array([100,200,300,400, 500])


op1 = np.column_stack((A,B))
tt = []
for i in C:
   tt.append(np.column_stack((op1, np.array([i]*A.shape[0]))))
   

print(np.concatenate(tt).reshape(C.shape[0],A.shape[0],3).transpose(1,0,2))

相关问题 更多 >