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或更高版本,则应该在那里.
这是一种使用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)