Многие потоки здесь показывают, что accumarray
- это ответ в Matlab для группировки (и вычисления) значений по наборам индексов. Поскольку это работает быстро и хорошо, мне нужно иметь что-то подобное для больших (ND) полей данных.
Давайте рассмотрим пример: у нас есть вектор имен с (неуникальными) именами внутри и вектор данных доходов для разные проекты по столбцам
names=str2mat('Tom','Sarah','Tom','Max','Max','Jon');
earnings=[100 200 20;20 100 500;1 5 900; 100 200 200;200 200 0; 300 100 -250];
и теперь мы хотим вычислить суммы столбцов для каждого имени.
Хорошо, мы можем узнать индексы по
[namesuq,i1,i2]=unique(names,'rows')
но после этого очевидный звонок
accumarray(i2,earning)
не работает. Можно, конечно, использовать цикл for для уникальных имен или строк, но это может быть немного неэффективно. Есть ли идеи получше?
Кроме того, я попробовал
accumarray(i2,@(i)earnings(i,:))
но это не реализовано и приводит к
Ошибка при использовании accumarray
Второй входной VAL должен быть полным числовым, логическим или символьным вектором или скаляром.
Спасибо за идеи.
Дополнения: спасибо eitan-t за его решение, которое отлично подходит для примера.
Так грустно, мой минимальный рабочий пример не показал всех потребностей: функция, которую я хочу применить, нуждается в целой строке или позже, возможно, в полной матрице, которую мне нужно сгруппировать по 3-му или даже более высокому измерению.
Может быть, чтобы было понятнее: подумайте о матрице M
размером a x b x c
, и каждая запись в a
соответствует имени или около того. Моя потребность лучше всего описана, например, суммированием всех уникальных имен.
Наивное программирование было бы
nam=unique(names);
for ind=1:size(nam,2)
N(ind,:,:)=sum(M(nam(ind)==names,:,:),1);
end
Это понятно? Есть ли решения для этого?