Search code examples
pythonrowsubmatrix

splitting matrix in multiple blocks


I have a matrix like that below:

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

and I want to extract submatrices containing equal rows. I don't know a priori how many blocks I'll get and the position of equal rows, since it is an example for a much bigger matrix.

The result I should obtain is in the form

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

I tried with


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)

but of course I only get separate couples of equal rows and not a single block.


Solution

  • The output of the following program will be a dict in which the keys being the name of the sub-matrices viz., B, C.. etc. And the values will be sub matrices with similar rows

    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]]
    
    # initiate variables i and dct, L being length of the matrix A
    i, L, dct = 0, len(A), {}
    
    # a list 'ref' to find out whether a row is already listed into sub-matrix
    ref = []
    
    while i < L:
        sub = []
    
        #Execute only if a row is not present in ref
        if A[i] not in ref:
        
            #Another list to iterate over which doesn't contain A[i]
            B = A[:i] + A[i+1:]
            
            for j, y in enumerate(B):
                if A[i] == y: sub.append(y)
                
                # if j is the last index in B, append A[i] to both sub and ref
                if j == len(B)-1:
                    sub.append(A[i])
                    ref.append(A[i])
            
            # Key of the dct being capital alphabets from 'B' and value being submatrix
            dct[chr(65 + len(ref))] = sub
        i += 1
    print(dct) 
    
    #Output: {'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]]}