【问题标题】:Reshaping/Combining several sub-matrices to one matrix in multi-dimensional space在多维空间中将多个子矩阵重塑/组合为一个矩阵
【发布时间】:2016-04-08 23:27:58
【问题描述】:

我有一个大小为 (2, 2, 4, 2, 2) 的 5D 二进制数组“a”。结构如下所示,例如:

a[0,0]:
[[[ 0.  1.]
  [ 0.  0.]]

 [[ 0.  0.]
  [ 0.  1.]]

 [[ 0.  0.]
  [ 0.  1.]]

 [[ 0.  0.]
  [ 1.  0.]]]

我要做的是制作一个 (2,2,4,4) 矩阵,它结合了最后两个轴上的 2x2 矩阵,但采用平方结构。

结果应该是这样的:

result[0,0]:
[[0. 1. 0. 0.]
 [0. 0. 0. 1.]
 [0. 0. 0. 0.]
 [0. 1. 1. 0.]]

我希望这已经足够清楚了。如果我把原始矩阵的括号放在结果中,它看起来像这样:

result[0,0]:
[[[0. 1. [0. 0.]
 [0. 0.] 0. 1.]]
 [[0. 0. [0. 0.]
 [0. 1.] 1. 0.]]]

【问题讨论】:

  • 不,还不够清楚。如果您提供了一个我们可以通过简单的剪切粘贴来使用的测试用例,将会有所帮助。否则我们可能会错过您目标的一些细微差别。
  • 最后添加的括号更令人困惑,很有帮助。

标签: python arrays numpy multidimensional-array vectorization


【解决方案1】:

首先,最好将您的数组索引为a[0,0]a[0,0,...]a[0,0,:,:]

a.reshape(2,2, 4,4) 做你想做的事吗?这会保留所有值,但会将最里面的 (2,2) 数组重塑为 (4,) 数组。

仔细观察,您似乎想要对内部数组中的值重新排序。从你的描述来看,这并不完全明显。我必须仔细匹配显示器之间的值。特别是只有 2 个子数组是明确的:

[[ 0.  0.]
  [ 0.  1.]]

 [[ 0.  0.]
  [ 1.  0.]]]

[0. 0. 0. 0.]
 [0. 1. 1. 0.]]

我们需要做的是在整形前转置最后两个轴。

这可能会奏效:

a.transpose(0,1,2,4,3).reshape(2,2,4,4)

它适用于np.ones((2,2,4,2,2)),但我没有使用与您的问题重复的数字对其进行测试 - 因为您没有提供可以剪切粘贴的测试用例。


哎呀 - 看起来 Divakar 是对的。我们需要将4 维度分解为2,2,并进行跨维度的转置。

In [290]: a=np.array([[[0,1],[0,0]],[[0,0],[0,1]],[[0,0],[0,1]],[[0,0],[1,0]]])
In [291]: a
Out[291]: 
array([[[0, 1],
        [0, 0]],

       [[0, 0],
        [0, 1]],

       [[0, 0],
        [0, 1]],

       [[0, 0],
        [1, 0]]])
In [292]: a.reshape(2,2,2,2).transpose(0,2,1,3).reshape(4,4)
Out[292]: 
array([[0, 1, 0, 0],
       [0, 0, 0, 1],
       [0, 0, 0, 0],
       [0, 1, 1, 0]])

这是一个更清晰的例子:

In [303]: a=np.arange((4*2*2)).reshape(4,2,2)
In [304]: a.reshape(2,2,2,2).transpose(0,2,1,3).reshape(4,4)
Out[304]: 
array([[ 0,  1,  4,  5],
       [ 2,  3,  6,  7],
       [ 8,  9, 12, 13],
       [10, 11, 14, 15]])

如果每个维度都不同,那就更好了,这样合并哪些维度的歧义就更少了。

In [308]: a=np.arange((6*5*7)).reshape(6,5,7)
In [309]: a.reshape(2,3,5,7).transpose(0,2,1,3).reshape(10,21)

【讨论】:

  • 谢谢。抱歉索引我的数组。我修好了
【解决方案2】:

您似乎将第三个轴从 (4) 分解为 (2,2) 并将分割轴的前半部分引入倒数第二个轴位置。所以,有两种方法可以使用np.reshapenp.transpose来实现这样的输出,就像这样-

out = a.reshape(2,2,2,2,2,2).transpose(0,1,3,4,2,5).reshape(2,2,4,4)

out = a.reshape(2,2,2,-1,2).transpose(0,1,3,2,4).reshape(2,2,4,4)

示例运行 -

In [69]: a[0][0]
Out[69]: 
array([[[49, 91],
        [10, 32]],

       [[71, 27],
        [50, 64]],

       [[ 9, 41],
        [73, 52]],

       [[54, 85],
        [53, 36]]])

In [70]: out1 = a.reshape(2,2,2,2,2,2).transpose(0,1,3,4,2,5).reshape(2,2,4,4)

In [71]: out2 = a.reshape(2,2,2,-1,2).transpose(0,1,3,2,4).reshape(2,2,4,4)

In [72]: out1[0][0]
Out[72]: 
array([[49, 91,  9, 41],
       [10, 32, 73, 52],
       [71, 27, 54, 85],
       [50, 64, 53, 36]])

In [73]: out2[0][0]
Out[73]: 
array([[49, 91,  9, 41],
       [10, 32, 73, 52],
       [71, 27, 54, 85],
       [50, 64, 53, 36]])

【讨论】:

  • 非常感谢!这几乎就是我想要的。我的问题在提及组合顺序方面模棱两可。因此,您首先将它们堆叠在顶部,然后向右移动。是否可以反过来做,使 out[0,0] 看起来像:[[49, 91, 71, 27], [10, 32, 50, 64], [9, 41, 54, 85], [50, 64, 53, 36]]
  • @Babak 最后一个不应该是[73, 52, 53, 36]吗?假设,应该这样做 - a.reshape(2,2,2,2,2,2).transpose(0,1,2,4,3,5).reshape(2,2,4,4) .
  • 非常感谢!你是一个真正的巫师
猜你喜欢
  • 2013-05-17
  • 2020-03-19
  • 1970-01-01
  • 1970-01-01
  • 2021-08-17
  • 2018-09-20
  • 2023-01-25
  • 2016-03-18
  • 1970-01-01
相关资源
最近更新 更多