python - numpy通过任意轴 reshape 多维数组

标签 python arrays numpy matrix

所以这是一个关于 reshape 的使用以及该函数如何在多维尺度上使用每个轴的问题。

假设我有以下数组,其中包含由第一个索引索引的矩阵。 我想要实现的是用第一个索引代替对每个矩阵的列进行索引。为了说明这个问题,请考虑以下示例,其中给定的 numpy 数组索引矩阵的第一个索引是 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 是一个矩阵。

那么更具体的问题是如何使用 reshape 来获得以下所需的输出:

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

形状是(6, 3)。这实现了数组的维度索引矩阵 x 和 y 的列,如上所示。我的自然倾向是按以下方式直接在 z 上使用 reshape:

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

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

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

是否可以使用 reshape 来获得上述所需的输出?或者更笼统地说,当你使用reshape函数时,你能控制每个轴的使用方式吗?

两件事:

  • 我知道如何解决这个问题。我可以通过转置大矩阵 (z) 的每个元素,然后以上述方式应用 reshape 。这会稍微增加计算时间,但问题不大。但是不泛化,没有python的感觉。所以我想知道是否有一种标准的开明方法可以做到这一点。

  • 我不清楚如何表述这个问题。如果有人对如何更好地表达这个问题提出建议,我会洗耳恭听。

最佳答案

每个数组的元素都有一个自然的(一维扁平化)顺序。当您 reshape 数组时,它好像先被展平(从而获得自然顺序),然​​后再 reshape :

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 相距很远。无论您如何 reshape 它,0 和 1 都不会沿着最后一个轴彼此相邻,这正是您在所需数组中想要的:

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

这需要一些重新排序,在本例中可以通过 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) 将值按所需顺序放置

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-)顺序数组并放置在 reshape 的数组中。但是,我认为这对您的情况没有帮助。


考虑 reshape 限制的另一种方法是说所有 reshapes 之后的 ravel 都是相同的:

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

所以如果想要的数组的解法不同,就没有办法得到,只能整形。


这同样适用于使用 order='F' 进行整形,前提是您还对 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])

可以使用两次整形获得所需的数组:

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

但我偶然发现了这个。


如果我完全误解了你的问题并且 xy 是给定的(不是 z)那么你可以获得所需的数组使用 row_stack 而不是 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]])

关于python - numpy通过任意轴 reshape 多维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35226115/

相关文章:

python - 访问 numpy 元组数组中的第一项

python - 找出一个点是否位于点云的凸包中的有效方法是什么?

python - 获取 numpy 数组中 N 个最大值的索引,并随机打破平局

python - Twilio 模块通过 Python 发送电子邮件内容

python - 如何调用不在工作目录中的python文件中的函数?

python - 线程被阻塞调用阻塞 - 如何在阻塞调用上设置超时?

c++ - OpenMP 上并行合并排序的数组大小问题。如何在更多任务上划分合并排序?

arrays - Powershell 相当于 Bash Brace Expansion 用于生成列表/数组

python - 用Python解析JSON,数组数组的麻烦

python - Python/NumPy 中 meshgrid 的用途是什么?