Matlab 从矩阵/向量中提取两个数字之间的元素

Matlab 从矩阵/向量中提取两个数字之间的元素,matlab,matrix,extract,Matlab,Matrix,Extract,例如,我有一个4x4矩阵 A = [1, 2, 3, 4; 2, 1, 4, 3; 1, 2, 4, 3; 4, 1, 2, 3;]; 对于每一行,我想提取1到3之间的元素,假设矩阵总是有一些元素在1到3之间,并且1总是在3之前。例如,返回类似[{2}、{4}、{2,4}、{2}]的单元格,或者使用矩阵返回更好的单元格 B= [0, 1, 0, 0;

例如,我有一个4x4矩阵

   A = [1,    2,    3,    4;
        2,    1,    4,    3;
        1,    2,    4,    3;
        4,    1,    2,    3;];
对于每一行,我想提取1到3之间的元素,假设矩阵总是有一些元素在1到3之间,并且1总是在3之前。例如,返回类似[{2}、{4}、{2,4}、{2}]的单元格,或者使用矩阵返回更好的单元格

B=  [0,    1,    0,    0;
     0,    0,    0,    1;
     0,    1,    0,    1;
     0,    1,    0,    0;];
现在我为每一行做一个循环,找到1和3的索引,然后将它们之间的索引设置为零,即

    B = zeros(4,4);
    for i = 1 : size(A,1)
        ind1 = find(A(i,:) ==1);
        ind2 = find(A(i,:) ==3);
        B(i, A(i,ind1+1:ind2-1) ) = 1;
    end

有没有更简单的方法来生成这个矩阵B或者只是单元?感谢您的建议。

好的,这可能不是一个简单的解决方案,但它确实消除了循环,因此计算速度应该更快:

我的想法不是试图找到介于1和3之间的数字并将其设置为1,而是找到1和3之外的数字并将其设置为0:

B=zeros(4,4);
B(A == 1) = 1;
B(A == 3) = 1;
C = cumsum(B')';
B(C>=2) =1;
B(C< 1) =1;

%finally you want to invert this:
B = (B-1)*-1;

>> B =

 0     1     0     0
 0     0     1     0
 0     1     1     0
 0     0     1     0

这将为A提供介于1和3之间的元素索引,然后您可以使用逻辑索引查找所需的单元格编号。

好的,这可能不是一个简单的解决方案,但它确实删除了循环,因此计算速度应该更快:

我的想法不是试图找到介于1和3之间的数字并将其设置为1,而是找到1和3之外的数字并将其设置为0:

B=zeros(4,4);
B(A == 1) = 1;
B(A == 3) = 1;
C = cumsum(B')';
B(C>=2) =1;
B(C< 1) =1;

%finally you want to invert this:
B = (B-1)*-1;

>> B =

 0     1     0     0
 0     0     1     0
 0     1     1     0
 0     0     1     0

这将为A提供介于1和3之间的元素索引,然后您可以使用逻辑索引来查找所需的单元格编号。

我的解决方案与已经提出的解决方案没有太大区别,但它有一个bsxfun,所以我说-为什么不呢?:

function B = q38307616

A = [1,    2,    3,    4;
     2,    1,    4,    3;
     1,    2,    4,    3;
     4,    1,    2,    3;];

At = A.';

tmp = arrayfun(@colon,find(At==1)+1,find(At==3)-1,'UniformOutput',false);
% [tmp{:}] gives us the indices of the elements we should be considering

B = 0*A; %preallocation
for ind1 = 1: numel(tmp)
  B(ind1,:) = sum(bsxfun(@eq,At(tmp{ind1}).',1:4),1); %1:4 are the allowable values
end
额外好处:获得每行1到3之间元素的逻辑映射(与B相同)的另一种方法是:


我的解决方案与已经提出的方案没有太大区别,但它有一个bsxfun,所以我说-为什么不呢

function B = q38307616

A = [1,    2,    3,    4;
     2,    1,    4,    3;
     1,    2,    4,    3;
     4,    1,    2,    3;];

At = A.';

tmp = arrayfun(@colon,find(At==1)+1,find(At==3)-1,'UniformOutput',false);
% [tmp{:}] gives us the indices of the elements we should be considering

B = 0*A; %preallocation
for ind1 = 1: numel(tmp)
  B(ind1,:) = sum(bsxfun(@eq,At(tmp{ind1}).',1:4),1); %1:4 are the allowable values
end
额外好处:获得每行1到3之间元素的逻辑映射(与B相同)的另一种方法是:


我不明白两者之间的定义。你是说你能找到[1 2 3]的地方吗?我不明白B的第三行和第四行,我想说的是,行的B对我来说似乎是正确的,我不知道中间是如何定义的。你是说你能找到[1 2 3]的地方吗?我不明白B的第三排和第四排,我想说的是B的B对我来说似乎是正确的,但是这个B不同于OPsB@AnderBiguri因为他最后做了个A.*B,让我把它放进去。但是。。。。这和OP在他的帖子里所说的还是不同的,rigth?我明白了,它已经被编辑过了now@AnderBiguri抱歉,已修复,但该循环很糟糕,我可能会更改它,但此B与OPs不同B@AnderBiguri因为他最后做了个A.*B,让我把它放进去。但是。。。。这和OP在他的帖子里所说的还是不同的,rigth?我明白了,它已经被编辑过了now@AnderBiguri抱歉,已修复,但该循环很糟糕,我可能会更改它