将矩阵转换为堆叠向量,其中每行的最后一个非零值之后的所有零都被移除

sha*_*aia 7 matlab vector matrix vectorization

我有一个矩阵,我想要擦除一些零值.

a=[ 1 2 3 0 0; 1 0 1 3 2; 0 1 2 5 0]

>>a =

 1     2     3     0     0
 1     0     1     3     2
 0     1     2     5     0
Run Code Online (Sandbox Code Playgroud)

但是,我想只擦除每行的最后一个非零值之后的那些.这意味着我想保留1 2 3第一行,1 0 1 3 2第二行和0 1 2 5第三行.

我想将剩余的值存储在向量中.在示例的情况下,这将导致向量

b=[1 2 3 1 0 1 3 2 0 1 2 5]
Run Code Online (Sandbox Code Playgroud)

我想出的唯一方法涉及一个for我想避免的循环:

b=[];
for ii=1:size(a,1)
    l=max(find(a(ii,:)));
    b=[b a(ii,1:l)];
end
Run Code Online (Sandbox Code Playgroud)

有没有办法对这段代码进行矢量化?

Gam*_*ows 10

有很多可能的方法可以做到这一点,这是我的方法:

 arotate = a' %//rotate the matrix a by 90 degrees
 b=flipud(arotate)  %//flips the matrix up and down
 c= flipud(cumsum(b,1)) %//cumulative sum the matrix rows -and then flip it back.
 arotate(c==0)=[] 

 arotate =

  1     2     3     1     0     1     3     2     0     1     2     5
Run Code Online (Sandbox Code Playgroud)

=========================编辑=====================

刚刚实现了cumsum可以有方向参数所以这应该做:

 arotate = a'
 b = cumsum(arotate,1,'reverse')
 arotate(b==0)=[] 
Run Code Online (Sandbox Code Playgroud)

此方向参数在我的2010b版本上不可用,但如果您使用的是2013a或更高版本,则应该在那里.


Div*_*kar 6

这是一种使用bsxfun屏蔽功能的方法 -

M = size(a,2); %// Save size parameter
at = a.'; %// Transpose input array, to be used for masked extraction

%// Index IDs of last non-zero for each row when looking from right side
[~,idx] = max(fliplr(a~=0),[],2);

%// Create a mask of elements that are to be picked up in a
%// transposed version of the input array using BSXFUN's broadcasting
out = at(bsxfun(@le,(1:M)',M+1-idx'))
Run Code Online (Sandbox Code Playgroud)

示例运行(以显示掩码使用情况) -

>> a
a =
     1     2     3     0     0
     1     0     1     3     2
     0     1     2     5     0
>> M = size(a,2);
>> at = a.'; 
>> [~,idx] = max(fliplr(a~=0),[],2);
>> bsxfun(@le,(1:M)',M+1-idx') %// mask to be used on transposed version
ans =
     1     1     1
     1     1     1
     1     1     1
     0     1     1
     0     1     0
>> at(bsxfun(@le,(1:M)',M+1-idx')).'
ans =
     1     2     3     1     0     1     3     2     0     1     2     5
Run Code Online (Sandbox Code Playgroud)