1

这里的许多线程表明这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,我需要将其分组到第三个甚至更高的维度。

也许更清楚一点:想想一个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

这清楚吗?有解决方案吗?

4

1 回答 1

2

基于这个答案,您正在寻找的解决方案是:

[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  
于 2013-08-27T11:27:05.380 回答