Возвратите уникальный элемент с допуском

В Matlab существует это unique управляйте что мускулы возвратов уникальные строки в массиве. Это - очень удобная команда.

Но проблема состоит в том, что я не могу присвоить допуск ему - в двойной точности, мы всегда должны сравнивать два элемента в точности. Существует ли встроенная команда, которая возвращает уникальные элементы, в рамках определенного допуска?

17
задан Andrey Rubshtein 26 January 2012 в 07:17
поделиться

3 ответа

Это сложная проблема. Я бы даже заявил, что ее вообще невозможно решить из-за того, что я бы назвал проблемой переходных процессов. Предположим, что у нас есть три элемента в наборе, {A,B,C}. Я определю простую функцию isSimilarTo, то естьSimilarTo(A,B) вернет истинный результат, если два входа находятся в пределах заданного допуска друг к другу. (Обратите внимание, что все, что я скажу здесь, имеет смысл как в одном измерении, так и в нескольких). Так что если известно, что два числа "похожи" друг на друга, то мы выберем группировку.

Так что предположим, что у нас есть значения {A,B,C}, то естьSimilarTo(A,B) истинно, и это также истинноSimilarTo(B,C). Должны ли мы решить сгруппировать все три вместе, даже если значениеSimilarTo(A,C) ложно?

Хуже, перейдем к двум измерениям. Начните с k точек, равномерно расположенных по периметру окружности. Предположим, что допуск выбран таким образом, что любая точка находится в пределах указанного допуска своих ближайших соседей, но не к любой другой точке. Как бы вы решили решить, какие точки "уникальны" в данной установке?

Я буду утверждать, что эта проблема интрансивности делает задачу группировки невозможной, по крайней мере, не идеальной, и уж точно не эффективной. Возможно, можно попробовать подход, основанный на k-среднем стиле агрегирования. Но и это будет весьма неэффективно, как правило, при таком подходе необходимо заранее знать количество групп, которые нужно искать.

Сказав это, я бы все-таки предложил компромисс, что-то такое, что иногда может работать в рамках. Трюк можно найти в Консолидаторе , который находится в центральном файлообменнике Matlab. Мой подход заключался в том, чтобы эффективно округлить входные данные в пределах указанного допуска. Сделав это, комбинация уникального и аккумуляторного массива позволяет эффективно производить агрегирование даже для больших наборов данных в одном или нескольких измерениях.

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

.
11
ответ дан 30 November 2019 в 11:17
поделиться

Я уже сталкивался с этой проблемой. Хитрость в том, чтобы сначала отсортировать данные, а затем с помощью функции diff найти разницу между каждым элементом. Затем сравнить, когда эта разница меньше, чем ваш допуск. Вот код, который я использую:

tol = 0.001
[Y I] = sort(items(:));
uni_mask = diff([0; Y]) > tol;
%if you just want the unique items:
uni_items = Y(uni_mask); %in sorted order
uni_items = items(I(uni_mask));  % in the original order

Это не заботится о "дрейфе" ... так что что что-то вроде 0:0.00001:100 на самом деле вернет одно уникальное значение.

Если вы хотите что-то, что может справиться с "дрейфом", то я бы использовал histc, но вам нужно сделать какую-нибудь грубую догадку, сколько элементов вы хотите иметь.

NUM = round(numel(items) / 10); % a rough guess
bins = linspace(min(items), max(items), NUM);
counts = histc(items, bins);
unit_items = bins(counts > 0);

BTW: Я написал это в текстовом редакторе вдали от matlab, так что там могут быть какие-то глупые опечатки или одна ошибка.

Надеюсь, это поможет

.
4
ответ дан 30 November 2019 в 11:17
поделиться
[

] Нет такой функции, о которой я знаю. Один хитрый аспект заключается в том, что если ваш допуск, скажем, 1e-10, и у вас есть вектор со значениями, которые равномерно распределены на 9e-11, то первая и третья запись не одинаковые, но первая - та же, что и вторая, а вторая - та же самая, что и третья - так сколько "уникальных"?[

] [

]Один из способов решить эту проблему - округлить свои значения с нужной точностью, а затем запустить уникальную на этом пути. Это можно сделать с помощью round2 ([]http://www.mathworks.com/matlabcentral/fileexchange/4261-round2[]) или следующим простым способом:[

] [
r = rand(100,1); % some random data
roundedData = round(r*1e6)/1e6; % round to 1e-6
uniqueValues = unique(roundedData);
] [

]Также это можно сделать с помощью команды hist, если точность не слишком высока:[

] [
r = rand(100,1); % create 100 random values between 0 and 1
grid = 0:0.001:1; % creates a vector of uniquely spaced values 
counts = hist(r,grid); % now you know for each element in 'grid' how many values there are
uniqueValues = grid(counts>0); % and these are the uniques
]
5
ответ дан 30 November 2019 в 11:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: