Рассчитать наиболее распространенные значения - PullRequest
4 голосов
/ 04 декабря 2009

Если у меня есть матрица A с n значениями от 65:90. Как мне получить 10 самых распространенных значений в A? Я хочу, чтобы результат представлял собой матрицу 10x2 B с 10 общими значениями в первом столбце и временами его появления во втором столбце.

Ответы [ 5 ]

5 голосов
/ 04 декабря 2009
A = [65 82 65 90; 90 70 72 82]; % Your data
range = 65:90;
res = [range; histc(A(:)', range)]'; % res has values in first column, counts in second.

Теперь все, что вам нужно сделать, это отсортировать массив res по второму столбцу и взять первые 10 строк.

sortedres = sortrows(res, -2); % sort by second column, descending
first10 = sortedres(1:10, :)
1 голос
/ 04 декабря 2009

Черт, вот еще одно решение, все простые встроенные команды

[V, I] = unique(sort(A(:)));
M = sortrows([V, diff([0; I])], -2);
Top10 = M(1:10, :);

Первая строка: сортирует все значения, а затем ищет смещение, где каждое новое значение начинается в отсортированном списке. Вторая строка: вычислить разницу смещений по уникальному значению и отсортировать результаты.

Кстати, я бы предложил этот метод, только если диапазон возможных чисел действительно велик, например, [0,1E8]. В этом случае некоторые другие методы могут получить ошибку нехватки памяти.

1 голос
/ 04 декабря 2009

Мы можем добавить четвертый вариант, используя tabulate из панели инструментов статистики:

A = randi([65 90], [1000 1]);   %# thousand random integers in the range 65:90
t = sortrows(tabulate(A), -2);  %# compute sorted frequency table
B = t(1:10, 1:2);               %# take the top 10
1 голос
/ 04 декабря 2009

это также можно решить с помощью accmarray

ncounts = accumarray(A(:),1);  %ncounts should now be a 90 x 1 vector of counts
[vals,sidx] = sort(ncounts,'descend');   %vals has the counts, sidx has the number
B = [sidx(1:10),vals(1:10)];

accumarray не так быстр, как следовало бы, но часто быстрее, чем другие операции этого типа. мне потребовалось несколько сканов его страницы справки, чтобы понять, какого черта он делает. для ваших целей это, вероятно, медленнее, чем решение по протоколу Гистка, но немного более прямолинейно.

- редактировать: забыл '1' в вызове accumarray.

1 голос
/ 04 декабря 2009

Это легко решается с помощью arrayfun ()

A = [...]; % Your target matrix with values 65:90
labels = 65:90 % Possible values to look for
nTimesOccured = arrayfun(@(x) sum(A(:) == x), labels);
[sorted sortidx] = sort(nTimesOccured, 'descend');

B = [labels(sortidx(1:10))' sorted(1:10)'];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...