在Mathematica中选择/删除矩阵中行/列的列表的有效方法 [英] Efficient way to pick/delete a list of rows/columns in a matrix in Mathematica

查看:677
本文介绍了在Mathematica中选择/删除矩阵中行/列的列表的有效方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题在某种程度上是我在这里提出的问题的继续:

This question is in a way a continuation of the question I asked here:Simple way to delete a matrix column in Mathematica to which @belisarius and @Daniel provided very helpful answers.

我通常想做的是从矩阵中提取特定的行和列,或者除去指定的行和列之后剩下的内容.因此,可以将其正式写为,找到TakeOperator和Drop Operator这样:

What I am generally trying to do is to extract from a matrix A specific lines and columns OR what remains after what those specified are removed. So this can be formally writtewn as, find TakeOperator and Drop Operator such that:

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

TakeOperator[A,{i1,..,ip},{j1,...,jq}]=(A[[ik]][[jl]]) (1<=k<=p, 1<=l<=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}];

We note 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}]

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的效率非常低.

While Table as described above does the trick, it is highly inefficient to use Table in that manner.

我只想举个例子,我以@ belisarius为例:

Just to give an idea, I took @ 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

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

Note: With respect to the use of Drop in the earlier post, I thought about using it as well, but when I checked the documentation, there was no suggestion of getting it done the way @belisarius and @daniel suggested. If the documentation could be updated in that direction in future releases, it would be helpful.

推荐答案

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

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

示例用法:

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

这篇关于在Mathematica中选择/删除矩阵中行/列的列表的有效方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆