这里的许多线程都表明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他的解决方案,这对于这个例子很有用 太可悲了,我最小的工作示例没有显示所有需求:我想要的功能需要整行或以后可能是一个完整的maxtrix,我需要在第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
这是否清楚?这里有解决方案吗?
答案 0 :(得分:2)
基于this answer,您正在寻找的解决方案是:
[namesuq, i1, i2] = unique(names, 'rows');
[c, r] = meshgrid(1:size(earnings, 2), i2);
y = accumarray([r(:), c(:)], earnings(:));
其中行匹配names(i1, :)
。
%// Sample input
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]
%// Sum along columns by names
[namesuq, i1, i2] = unique(names, 'rows');
[c, r] = meshgrid(1:size(earnings, 2), i2);
y = accumarray([r(:), c(:)], earnings(:))
结果总和为:
y =
300 100 -250
300 400 200
20 100 500
101 205 920
对应names(i1, :)
:
ans =
Jon
Max
Sarah
Tom