MATLAB: точный массив с матрицей в качестве значений (второй входной параметр)

У меня есть матрица со значениями percantage, где каждая строка представляет отдельное наблюдение. Мне нужно вычислить совокупный продукт, где эти значения соответствуют одному и тому же индексу. Я пытался использовать accumarray Функция, которая работает нормально и, как и ожидалось, до тех пор, пока я использую вектор-столбец в качестве значения (а не матрицы). Мне интересно, как лучше всего решить мою проблему, не просматривая отдельные столбцы матрицы ценностей?

Вот мой пример кода:

subs = [1;1;1;2;2;2;2;2;3;3;4;4;4];
vals1 = [0.1;0.05;0.2;0.02;0.09;0.3;0.01;0.21;0.12;0.06;0.08;0.12;0.05];

% This is working as expected
result1 = accumarray(subs,vals1, [], @(x) prod(1+x) -1)


vals2 = [vals1,vals1];

% This is not working as the second input parameter of accumarray
% apperently must be a vector (rather than a matrix)
result2 = accumarray(subs, vals2, [], @(x) prod(1+x) -1)

2 ответа

Для vals вы можете установить его как 1:size(vals2,1) и использовать его для извлечения строк vals2, Также требуется, чтобы функция возвращала ячейку.

result2 = accumarray(subs, 1:size(vals2,1), [], @(x) {prod(1+vals2(x,:),1)-1})

Вы можете объединить элементы ячейки:

result3 = vertcat(result2{:})

Или все в одну строку:

result3 = cell2mat( accumarray(subs, 1:size(vals2,1), [], @(x) {prod(1+vals2(x,:),1)-1}))

result3 =

   0.38600   0.38600
   0.76635   0.76635
   0.18720   0.18720
   0.27008   0.27008

Результат теста в Octave, сравнивающего три предложенных метода с использованием [10000 x 200] матрица в качестве входных данных:

subs = randi(1000,10000,1);
vals2 = rand(10000,200);

=========CELL2MAT========
Elapsed time is 0.130961 seconds.
=========NDGRID========
Elapsed time is 3.96383 seconds.
=========FOR LOOP========
Elapsed time is 6.16265 seconds.

Демо онлайн

Вам нужно добавить второй набор подписок на subs (так что это N-by-2) для обработки ваших 2D данных, которые все еще должны быть переданы как вектор N-элемента (то есть один элемент для каждой строки в subs). Вы можете создать новый набор 2D подписок, используя ndgrid:

[subs1, subs2] = ndgrid(subs, 1:size(vals2, 2));
result2 = accumarray([subs1(:) subs2(:)], vals2(:), [], @(x) prod(1+x) -1)

И результат с вашими примерами данных:

result2 =

    0.3860    0.3860
    0.7664    0.7664
    0.1872    0.1872
    0.2701    0.2701
Другие вопросы по тегам