将矩阵分割成多个块

问题描述 投票:0回答:1

我有一个如下所示的矩阵:

A= [[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]]

我想提取包含相等行的子矩阵。我事先不知道我会得到多少块以及相等行的位置,因为它是更大矩阵的示例。

我应该获得的结果是在表格中

B=[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]]

C= [[0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]]

我尝试过


for i in range(len(A)):  
    for j in range(i + 1, len(A)): 
        if np.array_equal(A[i], A[j]):
           cluster = np.vstack((A[i], A[j]))
           print(cluster)

但是当然我只能得到几对相同的行,而不是单个块。

python row submatrix
1个回答
0
投票

如果我正确理解您的代码和意图,问题是您在找到一对匹配时打印结果(

if np.array_equal(A[i], A[j])
),并且不要等到找到不匹配的对才返回。

最简单的策略是将每一行与下一行进行比较,当没有匹配时,吐出到目前为止的所有行。您可以在 for 循环、递归函数或生成器中执行此操作。这是循环版本:

sub_arrays = []
start_index = 0
for i, (row, nextrow) in enumerate(zip(A, A[1:])):
    if not (row==nextrow).all():
        sub_arrays.append(A[start_index:i+1])
        start_index = i+1
        
sub_arrays.append(A[start_index:])

这里

sub_arrays
是一个包含子矩阵的列表,如果您愿意,您可以将其替换为打印语句。

一些补充的评论

  • 通过执行
    A
    来迭代
    for row in A
    的行比使用
    for i in range(len(A)): row = A[i]
    更Pythonic。
  • 在 python 3.10+ 中,您可以将
    zip(A, A[1:])
    替换为
    itertools.pairwise(A)
  • 从您的代码中,我假设您只想将相等且连续的行聚集在一起。如果不是,答案看起来就会有点不同。
  • 我在我的解决方案中使用了
    numpy
    因为你已经在使用它了,但它也假设
    A
    是一个
    numpy
    数组。如果你不想这样假设,这里有一个纯 python 解决方案。它依赖于列表比较,如果您不确定是否可以依赖它,请为您的用例添加一些额外的检查。
sub_arrays = []
start_index = 0
for i, (row, nextrow) in enumerate(zip(A, A[1:])):
    if not row==nextrow:
        sub_arrays.append(A[start_index:i+1])
        start_index = i+1
        
sub_arrays.append(A[start_index:])
© www.soinside.com 2019 - 2024. All rights reserved.