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

微笑、不失礼 提交于 2019-11-29 05:03:33
WReach

Part directly supports lists of indices when slicing arrays. The following definitions exploit that:

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}}

Example use:

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 *)

You can also use explicit ranges in a way that is fairly efficient. They may provide some more 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 use of Span except offhand I do not see how to get it to work in this setting.

Daniel Lichtblau Wolfram Research

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!