3
votes

Given: square matrix, and list which represents the index of rows to be removed, and it also represent at the same time the index of the columns to be removed (it is square matrix, so only one list is needed).

output: the square matrix, with BOTH the rows and the columns columns in the list removed.

Assume valid list of indices.

This is an example enter image description here

So the above says to remove the second and the 4th rows, and also the second and the 4th column.

I could not figure how to use Delete[] to remove both rows and columns at the same time, and I really did not want to make a list of each individual element index I want to remove.

But I could use Delete to remove rows.

This below how I solved it, I removed the rows first, then transposed the matrix, and then removed the rows of the new matrix (which will be the columns of the original), then transposed the result back to obtain what I wanted.

like this:

a = {{0, 5, 2, 3, 1, 0}, {4, 3, 2, 5, 1, 3}, {4, 1, 3, 5, 3, 2}, {4, 
    4, 1, 1, 1, 5}, {3, 4, 4, 5, 3, 3}, {5, 1, 4, 5, 2, 0}};
del = {{2}, {4}};
a = Delete[a, del];
a = Delete[Transpose[a], del];
(a = Transpose[a]) // MatrixForm

my question: Is there a shorter way using Delete (or another one of those expert tricks) to do this in a better way ?

thanks

4
Duplicate of this question: stackoverflow.com/questions/6258349/… . Voting to close - Leonid Shifrin
This question, Efficient way to pick/delete a list of rows/columns in a matrix in Mathematica, is also related, in particular the reply by WReach - 681234

4 Answers

6
votes

In cases where you want to remove the same indexed columns and rows I would use Part. For example to see a with columns and rows 2 and 4 removed:

a[[{1, 3, 5, 6}, {1, 3, 5, 6}]] // MatrixForm

To make it more general you could create something in which you combine DeleteCases with Range and the list of column/row indexes but in the absence of further information I haven't tried to do that (yet).

Edit

remove[a_?MatrixQ, pos_List] := Module[{tmp, length = Length[a]},

  tmp = DeleteCases[Range[length], Alternatives @@ pos];

  a[[tmp, tmp]]

  ]

remove[a,{2,4}]
{{0, 2, 1, 0}, {4, 3, 3, 2}, {3, 4, 3, 3}, {5, 4, 2, 0}}

Edit2

remove2[a_?MatrixQ, pos_List] := Module[{tmp, length = Length[a]},

  tmp = Complement[Range[length], pos];

  a[[tmp, tmp]]

  ]

remove2[a,{2,4}]
{{0, 2, 1, 0}, {4, 3, 3, 2}, {3, 4, 3, 3}, {5, 4, 2, 0}}

test both of these for your real world problem.

4
votes

This should be a faster way to delete rows than the double transpose method:

a = {{0, 5, 2, 3, 1, 0},
     {4, 3, 2, 5, 1, 3},
     {4, 1, 3, 5, 3, 2},
     {4, 4, 1, 1, 1, 5},
     {3, 4, 4, 5, 3, 3},
     {5, 1, 4, 5, 2, 0}};
del = {{2}, {4}};

a = MapThread[Delete, {a, Table[del, {Length[a]}]}]

Timing varies, but in this somewhat contrived example it is faster:

a = Table[RandomReal[], {1000}, {10000}];
del = Map[List, Union[Table[RandomInteger[{1, 10000}], {100}]]];
Timing[Transpose[Delete[Transpose[a], del]];]

{0.25, Null}

Timing[MapThread[Delete, {a, Table[del, {Length[a]}]}];]

(0.125, Null}

1
votes

This is much less efficient than the Part method, but I find it somewhat more transparent, and there are times that matters more.

ReplacePart[a, {{2}, {4}, {_, 2}, {_, 4}} :> Sequence[]]
0
votes

You can certainly do your example with Drop:

Drop[a, {2, 4, 2}, {2, 4, 2}] // MatrixForm

I don't know how general this is, but maybe it will help set you off in the right direction.