问题
I have a matrix like this one:
8
8
8
2
2
2
6
6
7
7
7
1
1
6
6
6
6
8
8
0
6
8
8
1
6
6
There are fixed patterns that always repeat. I would like to detect them. They repeat according to these rules:
Lines with 7 followed by lines with a number which can be (0, 1 or 2), followed by a 6
Lines with 8 followed by lines with a number which can be (0, 1 or 2), followed by a 6
For each one of the values on a single pattern detected (independently from the number of lines they are composed of), write in a second column a number of rank, starting from 1 and incrementing each time a new pattern in column one is detected. This would be the result:
8 1
8 1
8 1
2 1
2 1
2 1
6 1
6 1
7 2
7 2
7 2
1 2
1 2
6 2
6 2
6 2
6 2
8 3
8 3
0 3
6 3
8 4
8 4
1 4
6 4
6 4
Column 2 encodes in each line the first pattern (series of values = 1 meaning that on this line there is data related to patter 1), the second pattern (values 2) and so on... How can I do that?
回答1:
Here's a solution that only uses the "closing tags" to split the matrix into parts:
function b = replaceValues(a)
closingTag = 6;
% Find all closing tag positions
clTagPos = a(:, 1) == closingTag;
% Keep only the "last" tags and add matrix start/end positions
splitPoints = [0; find(diff(clTagPos) == -1); length(a)];
% Split matrix into cell array
acell = mat2cell(a, diff(splitPoints));
% Replace the second column of each part with the corresponding non-zero value
bcell = cellfun(@(c)[c(:, 1) ones(length(c), 1)*c(find(c(:, 2), 1), 2)], acell, 'UniformOutput', 0);
% Convert back to matrix
b = cell2mat(bcell);
end
Example input-output in Matlab:
a =
8 0
8 0
8 0
2 1
2 1
2 1
6 0
6 0
7 0
7 0
7 0
1 2
1 2
6 0
6 0
6 0
6 0
8 0
8 0
0 3
6 0
8 0
8 0
1 4
6 0
6 0
>> b = replaceValues(a)
b =
8 1
8 1
8 1
2 1
2 1
2 1
6 1
6 1
7 2
7 2
7 2
1 2
1 2
6 2
6 2
6 2
6 2
8 3
8 3
0 3
6 3
8 4
8 4
1 4
6 4
6 4
来源:https://stackoverflow.com/questions/20607014/match-patterns-in-a-matrix-with-a-variable-number-of-lines-and-count-them-in-mat