numpy通过任意轴重塑多维数组 [英] numpy reshaping multdimensional array through arbitrary axis

查看:76
本文介绍了numpy通过任意轴重塑多维数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以这是一个有关重整形状的使用以及此功能如何在多维尺度上使用每个轴的问题.

so this is a question regarding the use of reshape and how this functions uses each axis on a multidimensional scale.

假设我有以下数组,其中包含由第一个索引索引的矩阵. 我要实现的是改为使用第一个索引对每个矩阵的列进行索引.为了说明此问题,请考虑以下示例,其中使用第一个索引对矩阵进行索引的给定numpy数组是z.

Suppose I have the following array that contains matrices indexed by the first index. What I want to achieve is to instead index the columns of each matrix with the first index. In order to illustrate this problem, consider the following example where the given numpy array that indexes matrices with its first index is z.

x = np.arange(9).reshape((3, 3))
y = np.arange(9, 18).reshape((3, 3))
z = np.dstack((x, y)).T

z的位置:

array([[[ 0,  3,  6],
    [ 1,  4,  7],
    [ 2,  5,  8]],

   [[ 9, 12, 15],
    [10, 13, 16],
    [11, 14, 17]]])

其形状为(2, 3, 3).在这里,第一个索引是两个图像,三个x 3是一个矩阵.

And its shape is (2, 3, 3). Here, the first index are the two images and the three x three is a matrix.

然后更具体地表达的问题是如何使用整形来获得以下所需的输出:

The question more specifically phrased then, is how to use reshape to obtain the following desired output:

array([[ 0,  1,  2],
   [ 3,  4,  5],
   [ 6,  7,  8],
   [ 9, 10, 11],
   [12, 13, 14],
   [15, 16, 17]])

其形状为(6, 3).这样就实现了数组的维索引了矩阵x和y的列,如上所述.我自然的倾向是通过以下方式直接在z 上使用重整形状:

Whose shape is (6, 3). This achieves that the dimension of the array indexes the columns of the matrix x and y as presented above. My natural inclination was to use reshape directly on z in the following way:

out = z.reshape(2 * 3, 3)

但是它的输出如下,它索引矩阵的行而不是列的索引:

But its output is the following which indexes the rows of the matrices and not the columns:

array([[ 0,  3,  6],
   [ 1,  4,  7],
   [ 2,  5,  8],
   [ 9, 12, 15],
   [10, 13, 16],
   [11, 14, 17]]

是否可以使用重塑来获得所需的输出?还是更笼统,您可以控制使用整形功能时每个轴的使用方式吗??

Could reshape be used to obtain the desired output above? Or more general, can you control how each axis is used when you use the reshape function?

两件事:

  • 我知道如何解决这个问题.我可以浏览转置的大矩阵(z)的每个元素,然后按照上述方式应用整形.这会稍微增加计算时间,并且并不是真正的问题.但是它不能一概而论,也不会感觉到python.所以我想知道是否有一种标准的开明方法.

  • I know how to solve the problem. I can go through each element of the big matrix (z) transposed and then apply reshape in the way above. This increases computation time a little bit and is not really problematic. But it does not generalize and it does not feel python. So I was wondering if there is a standard enlightened way of doing this.

我不清楚如何表达这个问题.如果有人对如何更好地表达这个问题有任何建议,我会为之倾听.

I was not clear on how to phrase this question. If anyone has suggestion on how to better phrase this problem I am all ears.

推荐答案

每个数组的元素都具有自然(一维展平)的顺序.当您对数组进行整形时,它就像是 一样先被展平(从而获得自然顺序),然​​后进行整形:

Every array has a natural (1D flattened) order to its elements. When you reshape an array, it is as though it were flattened first (thus obtaining the natural order), and then reshaped:

In [54]: z.ravel()
Out[54]: 
array([ 0,  3,  6,  1,  4,  7,  2,  5,  8,  9, 12, 15, 10, 13, 16, 11, 14,
       17])

In [55]: z.ravel().reshape(2*3, 3)
Out[55]: 
array([[ 0,  3,  6],
       [ 1,  4,  7],
       [ 2,  5,  8],
       [ 9, 12, 15],
       [10, 13, 16],
       [11, 14, 17]])

请注意,按照自然顺序",0和1相距很远.无论您重塑形状,0和1都不会沿着最后一个轴彼此相邻,这就是您想要的所需数组:

Notice that in the "natural order", 0 and 1 are far apart. However you reshape it, 0 and 1 will not be next to each other along the last axis, which is what you want in the desired array:

desired = np.array([[ 0,  1,  2],
                    [ 3,  4,  5],
                    [ 6,  7,  8],
                    [ 9, 10, 11],
                    [12, 13, 14],
                    [15, 16, 17]])

这需要重新排序,在这种情况下,可以通过swapaxes完成:

This requires some reordering, which in this case can be done by swapaxes:

In [53]: z.swapaxes(1,2).reshape(2*3, 3)
Out[53]: 
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11],
       [12, 13, 14],
       [15, 16, 17]])

因为swapaxes(1,2)将值按所需顺序放置

because swapaxes(1,2) places the values in the desired order

In [56]: z.swapaxes(1,2).ravel()
Out[56]: 
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17])

In [57]: desired.ravel()
Out[57]: 
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17])

请注意,reshape方法还具有一个order参数,该参数可用于控制(C-或F-)顺序,通过该顺序可以从数组中读取元素并将其放置在变形数组中.但是,我认为这对您没有帮助.

Note that the reshape method also has a order parameter which can be used to control the (C- or F-) order with which the elements are read from the array and placed in the reshaped array. However, I don't think this helps in your case.

考虑reshape的限制的另一种方法是说,所有重塑后跟ravel都是相同的:

Another way to think about the limits of reshape is to say that all reshapes followed by ravel are the same:

In [71]: z.reshape(3,3,2).ravel()
Out[71]: 
array([ 0,  3,  6,  1,  4,  7,  2,  5,  8,  9, 12, 15, 10, 13, 16, 11, 14,
       17])

In [72]: z.reshape(3,2,3).ravel()
Out[72]: 
array([ 0,  3,  6,  1,  4,  7,  2,  5,  8,  9, 12, 15, 10, 13, 16, 11, 14,
       17])

In [73]: z.reshape(3*2,3).ravel()
Out[73]: 
array([ 0,  3,  6,  1,  4,  7,  2,  5,  8,  9, 12, 15, 10, 13, 16, 11, 14,
       17])

In [74]: z.reshape(3*3,2).ravel()
Out[74]: 
array([ 0,  3,  6,  1,  4,  7,  2,  5,  8,  9, 12, 15, 10, 13, 16, 11, 14,
       17])

因此,如果所需数组的间距不同,则仅通过重塑就无法获得它.

So if the ravel of the desired array is different, there is no way to obtain it only be reshaping.

使用order='F'重塑效果也一样,只要您也喜欢order='F':

The same goes for reshaping with order='F', provided you also ravel with order='F':

In [109]: z.reshape(2,3,3, order='F').ravel(order='F')
Out[109]: 
array([ 0,  9,  1, 10,  2, 11,  3, 12,  4, 13,  5, 14,  6, 15,  7, 16,  8,
       17])

In [110]: z.reshape(2*3*3, order='F').ravel(order='F')
Out[110]: 
array([ 0,  9,  1, 10,  2, 11,  3, 12,  4, 13,  5, 14,  6, 15,  7, 16,  8,
       17])

In [111]: z.reshape(2*3,3, order='F').ravel(order='F')
Out[111]: 
array([ 0,  9,  1, 10,  2, 11,  3, 12,  4, 13,  5, 14,  6, 15,  7, 16,  8,
       17])


可以使用两种变形来获得所需的数组:


It is possible to obtain the desired array using two reshapes:

In [83]: z.reshape(2, 3*3, order='F').reshape(2*3, 3)
Out[83]: 
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11],
       [12, 13, 14],
       [15, 16, 17]])

但是我偶然发现了这个.

but I stumbled upon this serendipidously.

如果我完全误解了您的问题,并且xy是给定值(不是z),则可以使用row_stack而不是dstack获得所需的数组:

If I've totally misunderstood your question and x and y are the givens (not z) then you could obtain the desired array using row_stack instead of dstack:

In [88]: z = np.row_stack([x, y])

In [89]: z
Out[89]: 
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11],
       [12, 13, 14],
       [15, 16, 17]])

这篇关于numpy通过任意轴重塑多维数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆