2009-06-30 3 views
0

Я пытаюсь выяснить, как удалить элемент матрицы в MATLAB, если он отличается от любого другого элемента на 0,01. Я должен использовать все уникальные элементы матрицы в качестве пороговых значений для кривой ROC, которую я создаю, но мне нужен способ удалить значения, когда они находятся в пределах 0.01 друг от друга (поскольку мы предполагаем, что они в основном равным, если это так).Удаление аналогичных элементов в матрице

И помощь была бы принята с благодарностью!

Спасибо!

+1

Что делать, если у вас есть целая цепь ценностей? Например. ваша матрица содержит 0, .005, .01, .015, .02, .025 и т. д. Первая эквивалентна второй, второй и третьей и т. д. Это означает, что все они эквивалентны, но это, вероятно, не то, что вы хотите, не так ли? – balpha

+0

Должно ли это масштабироваться для матриц любого числа измерений или оно каким-то образом ограничено? Когда вы говорите «удалить», это заставляет меня думать, что оставшаяся матрица будет скудной. Это правильно или проще? –

+0

Матрицы, с которыми я работаю сейчас, будут иметь заданный 2D размер (они в конечном итоге достигают 10 000 × 10 000). Наверное, я недостаточно объяснил удаляющую часть, хотя теперь, когда я думаю об этом, я сначала помещал все свои матричные значения в вектор. Затем мне нужно пройти через вектор и удалить любые значения, которые отличаются менее чем на 0,01 (если они отличаются менее чем на 0,01, я предполагаю, что они имеют одинаковое значение) – 2009-07-01 18:33:59

ответ

1

Пусть все элементы в вашей матрице образуют граф G = (V, E) такой, что a существует ребро между двумя вершинами (u, v), если разница между ними меньше 0,01. Теперь построим матрицу смежности для этого графа и найдем элемент с наибольшей степенью. Удалите его и добавьте в список и удалите его соседи из своего графика и повторите, пока не осталось никаких элементов.

КОД:

%% Toy dataset 
    M = [1 1.005 2 ;2.005 2.009 3; 3.01 3.001 3.005]; 
    M = M(:); 
    A = false(numel(M),numel(M)); 
    for i=1:numel(M) 
     ind = abs(M-M(i))<=0.01; 
     A(i,ind) = 1; 
    end 
    C = []; 
    while any(A(:)) 
     [val ind] = max(sum(A)); 
     C(end+1) = M(ind); 
     A(A(ind,:),:) = 0; 
    end 

Это имеет время выполнения O (N^2), где ваша матрица имеет п элементов. Да, это медленно.

3

Если вы просто пытаетесь удалить соседние значения в пределах этого допуска от вектора, я хотел бы начать с чем-то вроде этого:

roc = ... 

tolerance = 0.1; 
idx = [logical(1) diff(roc)>tolerance)]; 
rocReduced = roc(idx); 

«rocReduced» теперь вектор со всеми значениями, которые Ждут» t имеют смежные значения в пределах допуска в исходном векторе.

Этот подход имеет два различных ограничения:

  1. оригинальный вектор «Рух» должен быть монотонным.
  2. Не более двух элементов в строке может находиться в пределах допуска, в противном случае весь участок будет удален.

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

Если производительность не является большой проблемой, вы, возможно, следующий итерационный алгоритм подойдет приложение:

roc = ... 
tolerance = 0.1; 
mask = true(size(roc)); % Start with all points 
last = 1; % Always taking first point 
for i=2:length(roc) % for all remaining points, 
    if(abs(roc(i)-roc(last))<tolerance) % If this point is within the tolerance of the last accepted point, remove it from the mask; 
    mask(i) = false; 
    else % Otherwise, keep it and mark the last kept 
    last = i; 
    end 
end 
rocReduced = roc(mask); 

Это обрабатывает несколько последовательных интервалов суб-допуска, не обязательно бросать все прочь. Он также обрабатывает немонотонные последовательности.

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

1

Из вашего описания не совсем понятно, как вы хотите обрабатывать цепочку значений (как указано в комментариях уже), например. 0,0 0,05 0,1 0,15 ... и что вы на самом деле имеете в виду, удалив элементы из матрицы: установите их в ноль, удалите весь столбец, удалите всю строку?

Для вектора, он может выглядеть следующим образом (аналогично решению Adams)

roc = ... 
tolerance = 0.1; 

% sort it first to get the similar values in a row 
[rocSorted, sortIdx] = sort(roc); 

% find the differing values and get their indices 
idx = [logical(1); diff(rocSorted)>tolerance)]; 
sortIdxReduced = sortIdx(idx); 

% select only the relevant parts from the original vector (revert sorting) 
rocReduced = roc(sort(sortIdxReduced)); 

код не тестировался, но должен работать с надеждой.

0

Прежде чем использовать пороговое значение или допуски, чтобы поддерживать все значения достаточно близко, вы можете использовать встроенную функцию matlab unique() для уменьшения прогона. Как правило, Matlab пытается ускорить свои встроенные функции, поэтому старайтесь использовать как можно больше встроенных функций.