如何根据第一个条目中的值从矩阵中提取行?

Nas*_*ser 4 wolfram-mathematica

这是Mathematica中另一个简单的"矩阵"问题.我想说明我是如何做到的,并询问是否有更好的答案.

我想根据第一列中的值(或任何列,我在这里使用第一列作为示例)从矩阵中选择所有"行".

比如说,在这个例子中找到第一个位置的条目<= 4的所有行:

    list = {{1, 2, 3},
           {4, 5, 8},
           {7 , 8, 9}}
Run Code Online (Sandbox Code Playgroud)

所以,结果应该是

            {{1,2,3},
             {4,5,8}}
Run Code Online (Sandbox Code Playgroud)

好吧,问题是我需要使用Position,因为Position返回的结果可以直接由Extract使用.(但不能被Part或[[]]使用,所以这就是为什么我只是看着Position []).

但是我不知道怎么告诉Position请将'搜索'模式限制为只有'第一列'所以我可以在一行中完成.

当我输入

pos = Position[list, _?(# <= 4 &)]
Run Code Online (Sandbox Code Playgroud)

它返回<= 4的所有条目的位置.

{{1, 1}, {1, 2}, {1, 3}, {2, 1}}
Run Code Online (Sandbox Code Playgroud)

如果我首先获得第一列,然后在其上应用位置,那么它就是可行的

  list = {{1, 2, 3},
          {4, 5, 8},
          {7 , 8, 9}};
   pos = Position[list[[All, 1]], _?(# <= 4 &)]
   Extract[list, pos]
   -->       {{1, 2, 3}, {4, 5, 8}}
Run Code Online (Sandbox Code Playgroud)

我也试过这个:

pos = Position[list, _?(# <= 4 &)];
pos = Select[pos, #[[2]] == 1 &]  (*only look at ones in the 'first' column*)

{{1, 1}, {2, 1}}---> 
Run Code Online (Sandbox Code Playgroud)

这给了我第一栏中的正确位置.要用它来查找所有行,我做了

pos = pos[[All, 1]] (* to get list of row positions*)
---> {1, 2}

list[[ pos[[1]] ;; pos[[-1]], All]]
{{1, 2, 3}, 
 {4, 5, 8}}
Run Code Online (Sandbox Code Playgroud)

因此,要总结,把他们放在一起,这是我做的:

方法1

 list = {{1, 2, 3},
         {4, 5, 8},
         {7 , 8, 9}};
 pos = Position[list[[All, 1]], _?(# <= 4 &)]
 Extract[list, pos]
  -->       {{1, 2, 3}, {4, 5, 8}}
Run Code Online (Sandbox Code Playgroud)

方法2

list = {{1, 2, 3},
      {4, 5, 8},
      {7 , 8, 9}}

pos = Position[list, _?(# <= 4 &)];
pos = Select[pos, #[[2]] == 1 &];
pos = pos[[All, 1]];
list[[ pos[[1]] ;; pos[[-1]], All]]

{{1, 2, 3}, 
{4, 5, 8}}

 The above clearly is not too good. 
Run Code Online (Sandbox Code Playgroud)

方法1是否在"正确"的功能方式之上才能做到这一点?

作为参考,这是我在Matlab中执行上述操作的方法:

EDU>> A=[1 2 3;4 5 8;7 8 9]
A =
     1     2     3
     4     5     8
     7     8     9

EDU>> A( A(:,1)<=4 , :)

     1     2     3
     4     5     8
Run Code Online (Sandbox Code Playgroud)

我正在尝试改进我在Mathematica命令中使用矩阵的"功能"处理,这是一个我觉得我不擅长使用列表的领域.我发现使用矩阵更容易.

问题是:Mathematica中是否有更短/更实用的方法?

谢谢

小智 7

您可以使用Pick [],如下所示:

Pick[list, list[[All, 1]], _?(# <= 4 &)]
Run Code Online (Sandbox Code Playgroud)


Sim*_*mon 5

以下怎么样?

In[1]:= list = {{1, 2, 3}, {4, 5, 8}, {7, 8, 9}};

In[2]:= Select[list, First[#] <= 4 &]

Out[2]= {{1, 2, 3}, {4, 5, 8}}
Run Code Online (Sandbox Code Playgroud)

这是你的matlab代码的松散翻译:

list[[Flatten[Position[Thread[list[[All, 1]] <= 4], True]]]]
Run Code Online (Sandbox Code Playgroud)

(当然,Flatten如果我使用Extract而不是,则不需要Part).

  • @Nasser:发生该错误是因为默认情况下,"Position"会查看表达式的所有级别.你必须限制级别和/或头部,例如`Position [list,_List?(First [#] <= 4&),{1}]` (2认同)