Идентификация (и удаление) последовательностей из вектора в Matlab / Octave - PullRequest
4 голосов
/ 28 мая 2011

Я пытаюсь удалить любую последовательность длиной 3 или более из вектора чисел в Matlab (или Octave). Например, с учетом вектора dataSet ,

dataSet = [1 2 3 7 9 11 13 17 18 19 20 22 24 25 26 28 30 31];

удаление всех последовательностей длиной 3 или более приведет к prunedDataSet:

prunedDataSet = [7 9 11 13 22 28 30 31 ];

Я могу использовать грубое решение, но я подозреваю, что есть более лаконичный (и, возможно, эффективный) способ сделать это с помощью векторных / матричных операций, но меня всегда смущает вопрос, дает ли что-то индекс или значение в указанном индексе. , Предложения?

Вот метод грубой силы, который я придумал:

dataSet = [1 2 3 7 9 11 13 17 18 19 20 22 24 25 26 28 30 31];
benign = [];
for i = 1:size(dataSet,2)-2;
    if (dataSet(i) == (dataSet(i+1)-1) && dataSet(i) == dataSet(i+2)-2);
        benign = [benign i ] ;
    end;
end;

remove = [];
for i = 1:size(benign,2);
    remove = [remove benign(i) benign(i)+1 benign(i)+2 ];
end;

remove = unique(remove);

prunedDataSet = setdiff(dataSet, dataSet(remove));

Ответы [ 2 ]

6 голосов
/ 28 мая 2011

Вот решение с использованием DIFF и STRFIND

%# define dataset
dataSet = [1 2 3 7 9 11 13 17 18 19 20 22 24 25 26 28 30 31];

%# take the difference. Whatever is part of a sequence will have difference 1
dds = diff(dataSet);

%# sequences of 3 lead to two consecutive ones. Sequences of 4 are like two sequences of 3
seqIdx = findstr(dds,[1 1]);

%# remove start, start+1, start+2
dataSet(bsxfun(@plus,seqIdx,[0;1;2])) = []
dataSet =

     7     9    11    13    22    28    30    31
4 голосов
/ 28 мая 2011

Вот попытка с использованием векторно-матричной записи:

s1 = [(dataSet(1:end-1) == dataSet(2:end)-1), false];
s2 = [(dataSet(1:end-2) == dataSet(3:end)-2), false, false];
s3 = s1 & s2;
s = s3 | [false, s3(1:end-1)] | [false, false, s3(1:end-2)];
dataSet(~s)

Идея такова: s1 верно для всех позиций, где перед a+1 стоит число a. s2 верно для всех позиций, где a отображается на две позиции раньше a+2. Тогда s становится истинным, когда выполняются оба предыдущих условия. Затем мы строим s таким образом, что каждое истинное значение распространяется на двух его преемников.

Наконец, dataSet(~s) сохраняет все значения, для которых вышеприведенные условия являются ложными, то есть он сохраняет числа, которые не являются частью 3-последовательности.

...