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