быстрый Вариант
Вы можете использовать bsxfun
в сочетании с sum
, чтобы вычислить этот
sum(bsxfun(@eq, Y, X.'), 2)
Объяснение
В этом примере bsxfun
выполняет заданную операцию на каждой комбинации элементов в X
и Y
. Операцией, которую мы используем, является eq
(проверка равенства). Результатом является матрица, которая имеет строку для каждого элемента в Y
и столбец для каждого элемента в X
. Он будет иметь значение 1
, если элемент в X
равен элементу в Y
, который соответствует данной строке.
bsxfun(@eq, Y, X.')
% 0 0 0 0 1 0 0 0 0 0 0
% 0 0 1 0 0 0 1 0 0 1 0
% 0 0 0 0 0 0 0 1 0 0 1
Затем можно суммировать по столбцам, чтобы подсчитать количество элементов в X
, которые были равны заданному значению в Y
.
sum(bsxfun(@eq, Y, X.'), 2)
% 1
% 3
% 2
В новых версиях MATLAB (с R2016b), вы можете опустить bsxfun
поскольку операция равенства будет автоматически транслироваться.
sum(Y - X.', 2)
А Память-Efficient Опция
Первый вариант не является наиболее эффективным, поскольку он требует создания матрицы, которая является [numel(Y), numel(X)]
элементы большой. Другой способ, который может быть больше памяти, может быть эффективно использовать второй выход ismember
в сочетании с accumarray
[tf, ind] = ismember(X, Y);
counts = accumarray(ind(tf), ones(sum(tf), 1), [numel(Y), 1], @numel);
Объяснение
ismember
используется для определения, если значения в одном массиве находятся в другой.Первый вход сообщает нам , если каждый элемент первого входа находится во втором входе, а второй вывод сообщает вам , где на втором входе был найден каждый элемент первого входа.
[tf, ind] = ismember(X, Y);
% 0 0 1 0 1 0 1 1 0 1 1
% 0 0 2 0 1 0 2 3 0 2 3
Мы можем использовать второй вход для группировки одинаковых значений вместе. Функция accumarray
выполняет именно это, она использует переменную ind
выше для определения групп, а затем применяет данную операцию к каждой группе. В нашем случае мы хотим просто определить количество элементов внутри каждой группы. Таким образом, чтобы сделать это, мы можем перейти на второй вход размер ind
входа (минус те, которые не соответствуют) из них, а затем использовать numel
как операция (подсчитывает число в каждой группе)
counts = accumarray(ind(tf), ones(sum(tf), 1), [numel(Y), 1], @numel);
% 1
% 3
% 2
Я пытался. Но я получаю ошибку «Out of memory». – Kristada673
@ Kristada673 Насколько велики 'X' и' Y'? – Suever
Довольно большой. X имеет 5,88 миллиона строк, а Y - 1,1 миллиона строк. – Kristada673