Search code examples
pythonlistmatrixlist-comprehensionpartitioning

List comprehension and matrix partitioning


So I have

mat = [[a_11, a_12, ... , a_1n],
       [a_21, a_22, ... , a_2n],
       ...
       [a_n1, a_n2, ... , a_nn]]

and I want to make a k * k sized square submatrix from this with values sampled from mat (1 < k < n), but if mat[x][y] is selected then I want mat[y][x] also be selected.

To clarify:

submat = [[mat[x_1][x_1], mat[x_1][x_2], ... mat[x_1][x_k]],
          [mat[x_2][x_1], mat[x_2][x_2], ... mat[x_2][x_k]],     
          ...
          [mat[x_k][x_1], mat[x_k][x_2], ... mat[x_k][x_k]]]

with x_1, x_2, ... , x_k randomly chosen and not identical (x_1, x_2, ... , x_k are integers which range from 0 to n).

For example, with this array (n = 4)

mat = [[1, 5, 7, 0],
       [2, 4, 3, 1],
       [4, 9, 8, 1],
       [1, 0, 9, 3]]

with k = 2 I want sampled results like:

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

I tried

ordDet = [0, 1, 2, 3]
random.shuffle(ordDet)

submat = [
         [mat[ordDet[0]][ordDet[0]], mat[ordDet[0]][ordDet[1]]],
         [mat[ordDet[1]][ordDet[0]], mat[ordDet[1]][ordDet[1]]]
                                                              ]

but is there a way to do this using list comprehension?


Solution

  • Would this work for you? Just define 'SUBMAT_WIDTH' for the submatrix

    This would work only if the input and output matrixes are square

    import random
    
    mat = [[0, 5, 3, 1],
           [2, 0, 4, 2],
           [3, 4, 0, 3],
           [2, 3, 5, 0]]
    #define submat width
    SUBMAT_WIDTH = 3
    
    #create list of all indexes and shuffle it
    randomindexes=[x for x in range(len(mat))]
    random.shuffle(randomindexes)
    
    #slice random indexes
    randomindexes = randomindexes[:SUBMAT_WIDTH]
    
    
    sub_mat = [[mat[x][y] for y in randomindexes ] for x in randomindexes]