【问题标题】:Is there a simple way to swap rows in a matrix to form identity matrix on left side有没有一种简单的方法可以交换矩阵中的行以在左侧形成单位矩阵
【发布时间】:2020-12-22 05:28:59
【问题描述】:

给定一个矩阵 A,它可以是正方形,但很可能是矩形;并且鉴于可以在 Rank(A) 最左边的列上形成一个单位矩阵,有没有一种很好的方法来进行行交换来实现这个单位矩阵?

例如,以

开头
import numpy as np
row1 = np.array([1, 0, 0, 2, 3])
row2 = np.array([0, 0, 1, 4, 5])
row3 = np.array([0, 1, 0, 6, 7])
A = np.array([row1, row2, row3])

我想要

row1 = np.array([1, 0, 0, 2, 3])
row2 = np.array([0, 1, 0, 6, 7])
row3 = np.array([0, 0, 1, 4, 5])
A = np.array([row1, row2, row3])

我希望这是通用的,可能需要交换超过 1 行,并且矩阵的大小没有限制。也不能保证交换将是相邻的行。时间不重要,即效率不重要。不需要交换列。构成 Rank(A) 单位矩阵的列将位于左侧。

更难的“测试用例”是

row1 = np.array([0, 0, 0, 0, 1, 5, 6, 7])
row2 = np.array([0, 0, 1, 0, 0, 1, 4, 2])
row3 = np.array([0, 0, 0, 1, 0, 6, 8, 4])
row4 = np.array([0, 1, 0, 0, 0, 1, 1, 1])
row5 = np.array([1, 0, 0, 0, 0, 6, 8, 4])
A = np.array([row1, row2, row3, row4, row5])

【问题讨论】:

  • 这能回答你的问题吗? Swap two rows in a numpy array in python
  • 看我的回答。如果您需要更多解释,请 Lmk。
  • 矩阵是否保证具有满秩,或者我们是否必须处理输入是秩为 3 的 4x5 矩阵的情况?
  • 此时我已经修剪了矩阵,使其具有满秩

标签: python python-3.x numpy sorting


【解决方案1】:

请注意,A 的 shuffled-identity 部分是一个酉矩阵。

并且由于单位矩阵的排列特性,这意味着您可以简单地将A 乘以A[:rows, :rows].T(恒等式部分):

rows = 3 # the number of rows

A = A[:rows, :rows].T.dot(A)

结果; A = :

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

谁的行被切换以形成身份。

【讨论】:

  • 这不适用于以下情况 'row1 = np.array([0, 0, 0, 0, 1, 5, 6, 7]) row2 = np.array([0 , 0, 1, 0, 0, 1, 4, 2]) row3 = np.array([0, 0, 0, 1, 0, 6, 8, 4]) row4 = np.array([0, 1 , 0, 0, 0, 1, 1, 1]) row5 = np.array([1, 0, 0, 0, 0, 6, 8, 4]) A = np.array([row1, row2, row3 , row4, row5]) rows = 5 A = A[:rows, :rows].dot(A)'
  • 这比基于将行复制到需要去的更“直接”的洗牌具有更糟糕的时间复杂度,但提问者 确实 说他们不关心效率.不过,当输入为浮点数时,我会有点担心某些矩阵乘法算法的舍入误差。
  • 我不知道如何让它变得更好,但我所做的只是添加 2 行,然后将它们弄乱一点
  • @GeorgeK 现在试试,我忘了转置。
  • 是的,非常好。我应该也能发现这一点。
【解决方案2】:

我有一个解决方案,但它可能(非常)未优化。请记住,此解决方案取决于与单位矩阵长度相对应的行数:

def find_RankA(arr):
    identity_len = arr.shape[0]
    new_arr = np.empty_like(arr)
    for row in arr:
        replacement_index = row[:identity_len].tolist().index(1)
        new_arr[replacement_index] = row
    return new_arr

if __name__ == '__main__':
    row1 = np.array([0, 0, 0, 0, 1, 5, 6, 7])
    row2 = np.array([0, 0, 1, 0, 0, 1, 4, 2])
    row3 = np.array([0, 0, 0, 1, 0, 6, 8, 4])
    row4 = np.array([0, 1, 0, 0, 0, 1, 1, 1])
    row5 = np.array([1, 0, 0, 0, 0, 6, 8, 4])
    A = np.array([row1, row2, row3, row4, row5])
    print(find_RankA(A))

(Feedback welcome)

我们可以将函数简化为:

def find_RankA(arr):
    new_arr = np.empty_like(arr)
    for row in arr:
        new_arr[row[:arr.shape[0]].tolist().index(1)] = row
    return new_arr

【讨论】:

    【解决方案3】:

    基于强制排序的方法:

    A[np.argsort(np.argmax(A[:,:len(A)], 1))]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-16
      • 1970-01-01
      • 2023-02-09
      • 2013-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多