2014-02-10 5 views
2

Предположим, что существует 2 вектора (i,j), A(10,1), B(10,1), которые получают случайные значения от [1,10] интервал. например.Найти, сколько раз происходит пара значений

A = [1 6 1 10 1 7 1 9 3 6] 
B = [7 2 3 5 6 8 7 9 10 2]. 

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

1 and 7 ⇒ 2 occurrences 
6 and 2 ⇒ 2 occurrences 
1 and 3 ⇒ 1 occurrence 
10 and 5 ⇒ 1 occurrence 
1 and 6 ⇒ 1 occurrence 
... 

т.д.

Так что окончательный массив/вектор C происходит, со всеми возможными парами и их подсчитывались возникновения с размером C(number_of_pairs,2).

+0

@RodyOldenhuis Спасибо за осветляющий редактирования! –

+0

@ LuisMendo: Я * думаю * это то, что означает OP ... :) –

+0

@RodyOldenhuis Спасибо! – Kots

ответ

1

Что-то вроде этого?

C = zeros(10); 

for k = 1:10 
    C(A(k), B(k)) = C(A(k), B(k)) + 1 
end 
+2

Обратите внимание, что вы получаете то же самое с 'accumarray ([A (:) B (:)], 1)' –

+0

Вам не нужен 'C = нули (10,10)' для этого? – Kots

+0

@ Kots 'zeros (10)' - это то же самое, что и «нули (10,10)». – Dan

3

Использование accumarray, а затем find:

A = [1 6 1 10 1 7 1 9 3 6]; 
B = [7 2 3 5 6 8 7 9 10 2]; %// data 

aa = accumarray([A(:) B(:)], 1); %// how many times each pair occurs 
[ii jj vv] = find(aa); 
C = [ii jj vv]; %// only pairs which occurr at least once 

В вашем примере, это дает

C = 
    6  2  2 
    1  3  1 
    10  5  1 
    1  6  1 
    1  7  2 
    7  8  1 
    9  9  1 
    3 10  1 

Или, возможно, aa или vv то, что вам нужно; Я не уверен, каков ваш желаемый результат.


Другой возможный подход, вдохновленный @Rody's answer:

mat = [A(:) B(:)]; 
[bb ii jj] = unique(mat, 'rows'); 
C = [mat(ii,:) accumarray(jj,1)]; 
+1

+1: * всегда * a +1 для правильного использования 'accumarray'! –

+1

Но будьте осторожны, что максимальный объем памяти памяти равен O (N²) (в отличие от O (N) для петлевого решения) –

+0

@RodyOldenhuis Я добавил другой подход, частично основанный на вашем ответе, который может использовать меньше памяти (в зависимости от как «уникально» работает внутри) –

2

Что-то вроде этого?

A = [1 6 1 10 1 7 1 9 3 6]; 
B = [7 2 3 5 6 8 7 9 10 2]; 

%// Find the unique pairs 
AB = [A;B].'; 
ABu = unique(AB, 'rows'); 

%// Count the number of occurrences of each unique pair 
%// (pretty sure there's a better way to do this...)  
C = arrayfun(@(ii) ... 
    [ABu(ii,:) sum(all(bsxfun(@eq, AB, ABu(ii,:)),2))], 1:size(ABu,1), ... 
    'UniformOutput', false); 
C = cat(1,C{:}); 

Результат:

C = 
    1  3  1 
    1  6  1 
    1  7  2 
    3 10  1 
    6  2  2 
    7  8  1 
    9  9  1 
    10  5  1 
+0

+1, но использование 'arrayfun', вероятно, не самый быстрый подход –

+0

@LuisMendo: Нет, возможно, нормальный' for'-loop работает быстрее. Ну что ж, твоя «аккумулировка» все равно кулер :) –

Смежные вопросы