【问题标题】:Change block order of a binary diagonal matrix更改二进制对角矩阵的块顺序
【发布时间】:2021-09-13 21:30:29
【问题描述】:

我有以下二进制矩阵(numpy 数组):

M = np.array([[1, 1, 0, 0], [1, 0, 0, 0], [0, 0, 1, 1], [0, 0, 1, 0]])

实际上,它在对角线上有两个三角形。 我想反转矩阵的块,使两个三角形出现在另一个对角线上,但保持相同的形状:

M = np.array([[0, 0, 1, 1], [0, 0, 1, 0], [1, 1, 0, 0], [1, 0, 0, 0]])

我尝试使用带有 sort_index() 的 Dataframe 以及可能的轴和升序组合,但它们都不起作用。

我该怎么做?

我需要一个通用代码,它也适用于对角线上有这些三角形结构的更大矩阵。

在视觉上,我想从: 至:

【问题讨论】:

  • IIUC,我认为最后一行的预期输出有错误(应该是[0, 1, 0, 0]
  • 有一个错误,但反过来。我刚刚修好了。
  • 如果数组是:array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15]]) ,你能给出预期的输出吗?
  • 鉴于三角形的解释,我真的不明白 OP 想要什么......
  • 我添加了一个视觉图像来试图澄清

标签: python numpy


【解决方案1】:

您需要暂时注入一个额外的维度来反转。为此,您必须知道沿轴的三角形的大小(或数量):

import numpy as np

# generate dummy input with 3 triangles of size 2
tri = np.array([[1, 1], [1, 0]])
zero = np.zeros_like(tri)
arr = np.block([[tri, zero, zero], [zero, tri, zero], [zero, zero, tri]])
# alternatively: arr = np.kron(np.eye(3), tri)

tri_size = tri.shape[0]
res = arr.reshape(-1, tri_size, arr.shape[-1])[::-1, ...].reshape(arr.shape)

上面输入:

array([[1, 1, 0, 0, 0, 0],
       [1, 0, 0, 0, 0, 0],
       [0, 0, 1, 1, 0, 0],
       [0, 0, 1, 0, 0, 0],
       [0, 0, 0, 0, 1, 1],
       [0, 0, 0, 0, 1, 0]])

输出:

array([[0, 0, 0, 0, 1, 1],
       [0, 0, 0, 0, 1, 0],
       [0, 0, 1, 1, 0, 0],
       [0, 0, 1, 0, 0, 0],
       [1, 1, 0, 0, 0, 0],
       [1, 0, 0, 0, 0, 0]])

如果原始数组的形状为(num_triangles * triangle_size, second_dim),则辅助数组的形状为(num_triangles, triangle_size, second_dim)

【讨论】:

    【解决方案2】:

    只需反向切割第二个轴:M[:, ::-1]

    输出:

    array([[0, 0, 1, 1],
           [0, 0, 0, 1],
           [1, 1, 0, 0],
           [0, 1, 0, 0]])
    

    注意。举一个明确的例子,这从:

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

    到:

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

    【讨论】:

    • 我在请求中犯了一个错误。我刚刚更新了它。无论如何感谢您的回答。
    【解决方案3】:

    尝试使用numpy.roll

    import numpy as np
    M = np.array([[1, 1, 0, 0], [1, 0, 0, 0], [0, 0, 1, 1], [0, 0, 1, 0]])
    M = np.roll(M,2,axis=1) # Axis 1 for row wise
    print(M)
    >>> array([
           [0, 0, 1, 1],
           [0, 0, 1, 0],
           [1, 1, 0, 0],
           [1, 0, 0, 0]])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-21
      • 2011-06-21
      • 1970-01-01
      • 2018-01-18
      • 2023-02-22
      • 1970-01-01
      • 2017-03-05
      相关资源
      最近更新 更多