Addition of certain consecutive elements along column in a matrix.

1 回表示 (過去 30 日間)
Jaladhar Mahato
Jaladhar Mahato 2018 年 1 月 11 日
コメント済み: Jaladhar Mahato 2018 年 1 月 11 日
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 Center および File ExchangeBiotech and Pharmaceutical についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by