Преобразование 2D-матрицы в 3D с использованием двух векторов отображения с категориальными значениями в MATLAB - PullRequest
2 голосов
/ 14 июня 2011

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

У меня есть M x N матрица значений типа double и два N x 1 вектора (массивы строк) с категориальными значениями. 1-й вектор содержит K уникальных значений, а 2-й - L уникальных значений, таких как K * L> = N.

Я хотел бы преобразовать исходную матрицу в трехмерную матрицу M x K x L. Таким образом, чтобы сохранить 1-е измерение, 2-е измерение будет соответствовать уникальным значениям в 1-м векторе, а 3-е измерение - уникальным значениям во 2-м вектор.

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

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

EDIT:

Вот некоторые случайные данные:

A = reshape(1:24,4,6);
v1 = {'s1','s1','s2','s2','s3','s3'}';
v2 = {'t1','t2','t1','t2','t1','t2'}';
idx = randperm(6); %# just to randomize
v1 = v1(idx);
v2 = v2(idx);
[M, N] = size(z); %# M=4, N=6
K = numel(unique(v1)); %# K=3
L = numel(unique(v2)); %# L=2

Мне нужно изменить форму матрицы A на 4x3x2 таким образом, чтобы столбец 1 страницы 1 соответствовал комбинации s1_t1, столбец 2 страницы 2 - s2_t2 и т. Д. В этом примере K * L равно N, поэтому все позиции будут иметь данные, но это не общий случай.

1 Ответ

2 голосов
/ 15 июня 2011

Вы можете использовать accumarray для этого. Обратите внимание, что grp2idx даст несколько неожиданные результаты, поскольку он начинает нумерацию с первого найденного уникального элемента вместо нумерации в соответствии с отсортированными значениями v1 или v2. Если вы не заботитесь о порядке, вы можете использовать, например, idx2=grp2idx(v1).

idx1 = ndgrid(1:M,1:N); %# rows
[~,idx2]=ismember(v1,unique(v1)); 
idx2 = repmat(idx2',M,1); 
[~,idx3]=ismember(v2,unique(v2));
idx3 = repmat(idx3',M,1);

out = accumarray([idx1(:),idx2(:),idx3(:)],A(:),[M,K,L],@(x)x,0);
...