在Mathematica中选择/删除矩阵中行/列列表的有效方法

Phi*_*hil 4 wolfram-mathematica matrix

这个问题在某种程度上延续了我在这里提出的问题:在Mathematica中删除矩阵列的简单方法是 @belisarius和@Daniel提供了非常有用的答案.

我通常要做的是从矩阵中提取特定的行和列,或者在删除指定的内容后剩下的内容.所以这可以正式写成,找到TakeOperator和Drop运算符,这样:

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

我们注意到Ic = {i'1,...,i'p'} = Complement[{1,...,Length[A]},{i1,...,ip}]; Jc = {j'1,... ,j'q'} = Complement[{1,...,Length[A]},{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}]

虽然Table如上所述,但以这种方式使用Table是非常低效的.

为了给出一个想法,我拿了@ belisarius的例子:

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
Run Code Online (Sandbox Code Playgroud)

注意:关于Drop在早期帖子中的使用,我也考虑过使用它,但是当我检查文档时,没有任何建议按照@belisarius和@daniel建议的方式完成它.如果在将来的版本中可以在该方向上更新文档,那将会很有帮助.

WRe*_*ach 8

Part切片数组时直接支持索引列表.以下定义利用了:

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}}
Run Code Online (Sandbox Code Playgroud)

使用示例:

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 *)
Run Code Online (Sandbox Code Playgroud)