как создать вектор на основе двух вспомогательных векторов в Matlab - PullRequest
0 голосов
/ 25 апреля 2020

Я создаю программу Matlab для обработки массива данных, который содержит конечные целые числа (необязательно быть последовательными). Пусть говорит, что мой массив данных - это A, мне нужно сначала найти уникальные значения A, который формирует вектор B, и мне нужно посчитать количество вхождений каждого уникального значения в A, которое дает другой вектор C. Наконец, мне нужен вектор E, который имеет ту же длину A, но со значением i-го элемента E, вычисленного как E(i) = C(k) с k = A(i)

У меня есть код для создания B и C следующим образом:

A=[5 5 1 1 3 1 3 11 9 6 -2];
[B, ia, ic]=unique(A);
C = accumarray(ic,1);

A может быть большим вектором, а элементы A могут быть очень разными и в широком диапазоне, мне интересно, существует ли какой-либо векторизованный подход для генерации массива E вместо следующего л oop метод

E = zeros(size(A));
for n=1:length(E)
  k=find(B==A(n));
  E(n) = C(k);
end

1 Ответ

1 голос
/ 25 апреля 2020

Как вы говорите, чтобы вычислить значения для E, вам нужно вычислить индексы в B, которые соответствуют каждому элементу в A, неофициально где A == B. Это, очевидно, не сработает, потому что A и B имеют разные размеры. Но мы можем получить то, что хотим, думая о вещах как о 2D-сетке. Переставьте один из векторов и сравните их.

A == B.'
% or for older versions of MATLAB (won't implicitly expand the different sized variables)
bsxfun(@eq, A, B.')

ans =

  7×11 logical array

   0   0   0   0   0   0   0   0   0   0   1
   0   0   1   1   0   1   0   0   0   0   0
   0   0   0   0   1   0   1   0   0   0   0
   1   1   0   0   0   0   0   0   0   0   0
   0   0   0   0   0   0   0   0   0   1   0
   0   0   0   0   0   0   0   0   1   0   0
   0   0   0   0   0   0   0   1   0   0   0
% to help visualise
% A = [5 5 1 1 3 1 3 11 9 6 -2];
% B = [-2 1 3 5 6 9 11];

Вы можете видеть, что для каждого столбца позиция 1 говорит нам, где мы можем найти этот элемент в A в векторе B , Мы можем использовать find, чтобы получить индексы строк каждого 1, и использовать это для вычисления E.

[indices, ~] = find(A == B.');
E = C(indices);

Конечный результат

Если вы хотите вычислить это с одной строкой кода , вы можете использовать сделать следующее

A=[5 5 1 1 3 1 3 11 9 6 -2];
[B, ia, ic]=unique(A);
C = accumarray(ic,1);
E = C(mod(find(B.' == A)-1, length(B))+1).';
% or for older versions of MATLAB
E = C(mod(find(bsxfun(@eq, A, B.'))-1, length(B))+1).';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...