NumPy:2D数组的重塑

4

给定以下输入 numpy 数组,形状为(n**2 * m, m),其中 n=2m=5

A = np.array([[  71.87,   47.8 ,   24.84,   25.31,   15.43],
              [ 174.8 ,  131.84,   57.57,   76.53,   48.5 ],
              [   4.4 ,    2.  ,    1.6 ,    1.  ,    0.  ],
              [  28.71,   15.  ,   10.5 ,    4.17,    2.52],
              [ 222.8 ,  123.59,    7.72,  -39.33,    4.65],
              [ 156.84,  138.17,   21.75,   80.86,   44.55],
              [  89.5 ,  133.01, -114.69,    1.  , -167.7 ],
              [  21.25,   19.57, -177.65,   57.38, -119.75],
              [ 162.33,    7.72,  -51.72,  117.31,  -87.87],
              [  77.57,   26.75,   36.64,    6.99,   25.97],
              [ 276.6 ,  275.31, -128.61,  105.7 ,  -86.5 ],
              [ 135.5 ,  232.67,    9.15,   -5.25,  -48.62],
              [ 325.31,  238.17,  -32.69,   41.55,    3.32],
              [ 126.53,  118.36,  -13.64,  104.64,    7.66],
              [ 522.25,  176.  , -338.05,  265.95, -411.87],
              [  16.67,  116.75, -255.25,  109.61, -397.18],
              [  15.43,  267.15,  159.63,    3.32,   30.31],
              [  48.5 ,   83.93,   63.47,   17.66,   70.16],
              [ 321.25,  213.55,    1.  ,  368.13, -261.55],
              [ 107.52,    5.25,  -89.25,  423.44,  -80.89]])

如何重新塑造和排列A的轴,以便获得形状为(n*m, n*m)的下列输出B
B = np.array([[  71.87,  174.8 ,  222.8 ,  156.84,  162.33,   77.57,  325.31,  126.53,   15.43,   48.5 ],
              [   4.4 ,   28.71,   89.5 ,   21.25,  276.6 ,  135.5 ,  522.25,   16.67,  321.25,  107.52],
              [  47.8 ,  131.84,  123.59,  138.17,    7.72,   26.75,  238.17,  118.36,  267.15,   83.93],
              [   2.  ,   15.  ,  133.01,   19.57,  275.31,  232.67,  176.  ,  116.75,  213.55,    5.25],
              [  24.84,   57.57,    7.72,   21.75,  -51.72,   36.64,  -32.69,  -13.64,  159.63,   63.47],
              [   1.6 ,   10.5 , -114.69, -177.65, -128.61,    9.15, -338.05, -255.25,    1.  ,  -89.25],
              [  25.31,   76.53,  -39.33,   80.86,  117.31,    6.99,   41.55,  104.64,    3.32,   17.66],
              [   1.  ,    4.17,    1.  ,   57.38,  105.7 ,   -5.25,  265.95,  109.61,  368.13,  423.44],
              [  15.43,   48.5 ,    4.65,   44.55,  -87.87,   25.97,    3.32,    7.66,   30.31,   70.16],
              [   0.  ,    2.52, -167.7 , -119.75,  -86.5 ,  -48.62, -411.87, -397.18, -261.55,  -80.89]])

这个转换可以通过使用for循环轻松完成,但由于我需要效率,因此我正在寻找一个基于合适的reshape的解决方案,并对其背后的逻辑进行一些澄清。

任何帮助将不胜感激。


1
你的值发生了变化,例如从 162.33 变成了 162.34,在你期望的输出中索引为 [0,4]。这背后的逻辑是什么? - Michael Szczesny
请您提供一下for循环的答案。不太清楚您是如何将原始的转换成最后一个的。 - Ehsan
@MichaelSzczesny,抱歉,这些值来自不同的方法,由于指定了精度以获得小矩阵用于此问题和np.set_printoptions kwargs,它们可能不是非常接近。 - Yacola
2个回答

2
在查看您的数据时,需要稍微仔细一点,才能发现在输出中,A 的列已经被分块为 n*n 的块,并且铺成了 n x n 的正方形。例如,B[:2, :2] 的值是 A[:4, 0]
因此,关键是尝试将这些块放入连续的维度中,然后使用适当轴的转置,最后进行最终的重塑。
简而言之:
B = np.reshape(np.reshape(A.T, (m, m, n, n)).transpose(0, 2, 1, 3), (n*m, n*m))

1
你可以使用通常的reshapeswapaxesreshape来进行块状重塑。 @divakar发布了一份详细的解释
A.T.reshape(5,5,2,2).swapaxes(1,2).reshape(10,-1)

输出:
array([[  71.87,  174.8 ,  222.8 ,  156.84,  162.33,   77.57,  325.31, 126.53,    15.43,   48.5 ],
       [   4.4 ,   28.71,   89.5 ,   21.25,  276.6 ,  135.5 ,  522.25,  16.67,   321.25,  107.52],
       [  47.8 ,  131.84,  123.59,  138.17,    7.72,   26.75,  238.17, 118.36,   267.15,   83.93],
       [   2.  ,   15.  ,  133.01,   19.57,  275.31,  232.67,  176.  , 116.75,   213.55,    5.25],
       [  24.84,   57.57,    7.72,   21.75,  -51.72,   36.64,  -32.69, -13.64,   159.63,   63.47],
       [   1.6 ,   10.5 , -114.69, -177.65, -128.61,    9.15, -338.05, -255.25,    1.  ,  -89.25],
       [  25.31,   76.53,  -39.33,   80.86,  117.31,    6.99,   41.55,  104.64,    3.32,   17.66],
       [   1.  ,    4.17,    1.  ,   57.38,  105.7 ,   -5.25,  265.95,  109.61,  368.13,  423.44],
       [  15.43,   48.5 ,    4.65,   44.55,  -87.87,   25.97,    3.32,    7.66,   30.31,   70.16],
       [   0.  ,    2.52, -167.7 , -119.75,  -86.5 ,  -48.62, -411.87, -397.18, -261.55,  -80.89]])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接