Efficient way to select / delete a list of rows / columns in a matrix in Mathematica

This question is to some extent a continuation of the question I asked here: A simple way to remove a matrix column in Mathematica , which @belisarius and @Daniel provided very useful answers.

What I usually try to do is extract specific rows and columns from the matrix OR what is left after deleting the specified ones. Thus, this can be formally violated, since find FindOperator and Drop Operator to:

TakeOperator [A, {i1, .., ip}, {j1, ..., jq}] = (A [[ik]] [[jl]]) (1 <= k <= p, 1 <= lt ; = l <= q) = Table[A[[ik]][[jl]],{k,p},{l,q}]

Note that Ic = {i'1, ..., i'p '} = Complement [{1, ..., Length [A] }, {i1, ..., Ο†}]; Jc = {J'1, ..., j'q '} = Complement [{1, ..., <code> Length [A] code>}, {j1, ..., JQ}];

DropOperator [A, {i1, .., ip}, {j1, ..., jq}] = (A [[ik]] [[jl]]) (1 <= k '<= p', 1 < = l '<= q') = Table[A[[ik']][[jl']],{k',p'},{l','q}]

Although Table , as described above, does the trick, it is very inefficient to use a table this way.

Just to give an idea, I took the @belisarius example:

 In: First@Timing [a = RandomInteger[1000, {5000, 5000}];] Out:0.218 In:Clear[b,c] In: First@Timing [ b = Table[ If[i < 100, If[j < 100, a[[i]][[j]], a[[i]][[j + 1]]], If[j < 100, a[[i + 1]][[j]], a[[i + 1]][[j + 1]]]], {i, 4999}, {j, 4999}]] Out:140.807 In: First@Timing [c = Drop[a, {100}, {100}]] Out:0.093 In:c===b Out:True 

Note. Regarding the use of Drop in an earlier post, I thought about using it as well, but when I checked the documentation, there was no suggestion to do it the way @belisarius and @daniel did, If the documentation could be updated In this direction in future releases, it would be helpful.

+4
source share
2 answers

Part supports index lists when cutting arrays. The following definitions use the following:

 takeOperator[a_?MatrixQ, rows_List, cols_List] := a[[rows, cols]] dropOperator[a_?MatrixQ, rows_List, cols_List] := a[[##]]& @@ complementaryIndices[a, rows, cols] complementaryIndices[a_?MatrixQ, rows_List, cols_List] := Complement @@@ Transpose @ {Range /@ Dimensions @ a, {rows, cols}} 

Usage example:

 a = RandomInteger[1000, {5000, 5000}]; First @ Timing @ takeOperator[a, Range[1, 5000, 2], Range[1, 5000, 2]] (* 0.016 *) First @ Timing @ dropOperator[a, Range[1, 5000, 2], Range[1, 5000, 2]] (* 0.015 *) 
+8
source

You can also use explicit ranges in a fairly efficient way. They can provide some flexibility. Here is your example.

 a = RandomInteger[1000, {5000, 5000}]; Timing[b = Drop[a, {101}, {101}];] 

Out [66] = {0.041993, Null}

 Timing[ c = a[[Join[Range[100], Range[102, 5000]], Join[Range[100], Range[102, 5000]]]];] 

Out [67] = {0.061991, Null}

 c == b 

Out [62] = True

I would also suggest using Span, except as carelessly; I don’t see how to make it work in this setting.

Daniel Lichtblow Wolfram Research

+3
source

All Articles