# Identifying rows and columns of a matrix that satisfy a specific feature

Originally, I have a matrix of dimension (1040, 1040). This a very large matrix to visually inspect some features. I mimic the matrix of concern as:

mat={
{1, 2, 3, 0, 5, 6, 7, 0, 9, 10, 11, 0, 13, 14, 15, 0},
{17, 18, 19, 0, 21, 22, 23, 0, 25, 26, 27, 0, 29, 30, 31, 0},
{33, 34, 35, 0, 37,38, 39, 0, 41, 42, 43, 0, 45, 46, 47, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{65, 66, 67, 0, 69, 70, 71, 0, 73, 74, 75, 0, 77, 78, 79, 0},
{81, 82, 83, 0, 85, 86, 87, 0, 89, 90, 91, 0, 93, 94, 95, 0},
{97,98,99,0,101,102, 103, 0, 105, 106, 107, 0,109, 110, 111, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{129,130,131,0,133,134,135,0,137,138,139,0,141,142,143, 0},
{145,146,147,0,149,150,151,0,153,154,155,0,157, 158, 159, 0},
{161,162,163,0,165,166,167,0,169,170, 171, 0, 173, 174, 175, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{193, 194, 195, 0,197,198, 199, 0,201,202,203,0,205,206,207, 0},
{209,210,211,0,213, 214, 215, 0, 217, 218,219,0,221,222,223, 0},
{225, 226, 227, 0, 229, 230, 231,0,233,234,235,0,237,238,239,0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
}


As seen, matrix mat has some rows and columns with all zero entries.

1. I like to identify those rows and columns with all zero entries. For example, using mat, I like to have a list of row indices showing the row index numbers associated with zero-entry rows: {4, 8, 12, 16}. Likewise, for the column index, {4, 8, 12, 16}.
2. Then, after constructing the row/column index lists, I like to remove those zero rows/columns from the original matrix mat.

Using Drop[mat,{.,.},{.,.}], I can accomplish the above goal for the given matrix mat as zero rows and columns are placed systematically. But my problem is that I cannot see the actual mat visually and the zero rows/columns are unsystematically placed.

• The following will do what you want: Transpose[Transpose[mat] /. {0 ..} -> Nothing[]] /. {0 ..} -> Nothing[] – Daniel Huber Jan 27 at 15:44

nonzerorows = Flatten @ Position[mat, Except @ {0 ..}, 1, Heads -> False]

{1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15}

nonzerocols = Flatten @ Position[Transpose @ mat, Except @ {0 ..}, 1, Heads -> False]

{1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15}

mat1 = mat[[nonzerorows, nonzerocols]];

mat1 // MatrixForm


{zerorows, zerocols} = MapThread[Complement[Range @ # @ Dimensions[mat], #2] &,
{{First, Last}, {nonzerorows, nonzerocols}}]

 {{4, 8, 12, 16}, {4, 8, 12, 16}}

mat2 = DeleteCases[{}] @ ReplacePart[mat,
{Alternatives @@ zerorows, _} | {_, Alternatives @@ zerocols} -> Nothing];

mat2 == mat1

 True


You can get the final matrix directly using

mat3 = Nest[DeleteCases[{0 ..}] @* Transpose, mat, 2]

mat3 == mat1

True


One possibility is:

z = Position[mat, {0 ..}];
c = Position[Transpose@mat, {0 ..}];

Delete[Transpose@Delete[mat // Transpose, c], z]


An alternative is:

Select[Transpose[Select[mat, Not[And @@ PossibleZeroQ[#]] &]],
Not[And @@ PossibleZeroQ[#]] &] // Transpose


A row of all zeros also sums to zero... so you can apply Total to sum the elements of each row and then select the positions that are zero:

Position[Total[mat], _?((# == 0) &)]

{{4}, {8}, {12}, {16}}


If you just want the row numbers, you can Flatten. For columns, do the same thing to the transpose of mat. If your matrix has both positive and negative entries, apply Abs to mat.

• In the example matrix I gave above, it happens to be that all the entries are greater or equal to zero. However, my original matrix has both positive and negative entries, which may create zero Total, while the individual entries are not zero. – Tugrul Temel Jan 27 at 16:34
• Then use Abs when you sum... – bill s Jan 27 at 19:02
• That is right. Thank you very much. I have now many alternative formulations to consider. – Tugrul Temel Jan 27 at 19:19