Addition of certain consecutive elements along column in a matrix.

1 次查看(过去 30 天)
I have a matrix A, where only one '1' is present in a particular row.
A=[
0 0 0 0 1;
1 0 0 0 0;
1 0 0 0 0;
0 0 1 0 0;
0 0 0 0 1;
0 0 0 0 1;
0 0 0 0 1;
0 0 0 0 1;
0 0 1 0 0;
0 0 1 0 0;
0 0 0 0 1;
0 0 0 0 1]
Now I want to add all the consecutive '1' along columns whose out put will be B.
B[
0 0 0 0 1;
2 0 0 0 0;
0 0 1 0 0;
0 0 0 0 4;
0 0 2 0 0;
0 0 0 0 2]
  3 个评论
Jaladhar Mahato
Jaladhar Mahato 2018-1-11
I have a very big matrix of A. Here each column represents a state of my interest and the rows are time. As You can see for a particular row (time) only one state is on. Now I want to know the length of time where a state is "on" and when it switches its state. Now after the switch how much time, it spent in that state. I think this is enough.
Jos (10584)
Jos (10584) 2018-1-11
But why stores this in a matrix like B? Wouldn't your rather want the output to be like
5 1
1 2
3 1
5 4
3 2
5 2
Where the first column indicates the row where the sequence of 1's start, and the second column the number of 1's in the sequence? From this you can easily build the matrix B

请先登录,再进行评论。

采纳的回答

Guillaume
Guillaume 2018-1-11
编辑:Guillaume 2018-1-11
This should do it:
A=[
0 0 0 0 1;
1 0 0 0 0;
1 0 0 0 0;
0 0 1 0 0;
0 0 0 0 1;
0 0 0 0 1;
0 0 0 0 1;
0 0 0 0 1;
0 0 1 0 0;
0 0 1 0 0;
0 0 0 0 1;
0 0 0 0 1];
assert(all(sum(A, 2)) == 1), 'A must have one and only one 1 per row');
transitions = diff([zeros(1, size(A, 2)); A; zeros(1, size(A, 2))]); %identify starts (1) and ends (-1) of sequences in each column
[transrow, transcol] = find(transitions); %get location.
%Note that since find works columnwise, transx(1:2:end) is the start of sequence, and transy(2:2:end) is the end
seqlengths = transrow(2:2:end) - transrow(1:2:end); %length of sequences
B = zeros(size(A));
B(sub2ind(size(B), transrow(1:2:end), transcol(1:2:end))) = seqlengths; %put sequence length at start locations
B(~any(B, 2), :) = [] %and remove empty rows
edit: I agree with Jos that storing the result as a two column matrix of columnnumber length would make more sense. That is easily obtained with:
C = [transcol(1:2:end, seqlengths];
[~, order] = sort(transrow(1:2:end));
C = C(order, :)
without needing to build B.

更多回答(1 个)

Jos (10584)
Jos (10584) 2018-1-11
if ~all(sum(A,2)==1)
error('invalid input!')
end
Z = zeros(1,size(A,2))
dA = diff([Z ; A ; Z], 1, 1).'
[C,r1] = find(dA == 1)
[~,r2] = find(dA == -1)
N = r2 - r1
% C and N hold all the information you need to create B
B = zeros(numel(C), size(A,2))
idx = sub2ind(size(B), 1:size(B,1), C(:).')
B(idx) = N

类别

Help CenterFile Exchange 中查找有关 Biotech and Pharmaceutical 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by