我有两个如下形式的数组:
v1 = [ 1 2 3 4 5 6 7 8 9 ... ]
c2 = { 'a' 'a' 'a' 'b' 'b' 'c' 'c' 'c' 'c' ... }(所有值仅为示例,在真实数据中不能假设任何模式。v1和c2大小相同)
我想要获得一个向量,该向量包含与c2中的相等值对应的v1分量的总和。在上面的示例中,结果向量的第一个分量是1+2+3,第二个4+5,依此类推。
我知道我可以在表单的循环中完成:
uni_c2 = unique(c2);
result = zeros(size(uni_c2));
for i = 1:numel(uni_c2)
result(i) = sum( v1(strcmp(uni_c2(i),c2)) );
end 是否有一个单一的命令或矢量化的方式来执行相同的操作?
发布于 2011-11-06 21:45:20
您可以在两行代码中完成此操作:
[b, m, n] = unique(c2)
result = accumarray(n', v1)result的元素对应于单元阵列b中的字符串。
发布于 2011-11-06 11:27:03
这是矢量化的,但对于非常大的向量来说,这不是一个好主意。对于某些问题,“向量化”的解决方案比for循环更糟糕。
>> v1 = [ 1 2 3 4 5 6 7 8 9];
>> c2 = 'aaabbcccc'-'a'
c2 =
0 0 0 1 1 2 2 2 2
>> N = repmat(c2',1,max(c2)-min(c2)+1) == repmat([min(c2):max(c2)],size(c2,2),1);
>> v1*N
ans =
6 9 30发布于 2011-11-06 19:03:03
我认为一个非常通用的(和矢量化的)解决方案是这样的:
v1 = [ 1 2 3 4 5 6 7 8 9 ]
c2 = { 'a' 'a' 'a' 'b' 'b' 'c' 'c' 'c' 'c' }
uniqueValuesInC2 = unique(c2);
conditionalSumOfV1 = @(x)(sum(v1(strcmp(c2, x))));
result = cellfun(conditionalSumOfV1, uniqueValuesInC2)也许我的解决方案需要向未受过训练的人解释一下:
因此,首先您实际上需要在c2中计算不同的可能值,这是由unique完成的。
conditionalSumOfV1函数接受参数x,它将c2中的每个元素与x进行比较,并在v1中选择相应的元素并对它们求和。
最后,cellfun可与其他语言中的foreach结构相媲美:对于您提供的单元格数组中的每个值(在本例中:c2中的每个唯一值),都会对函数conditionalSum求值,并将其存储在输出数组中。对于其他类型的容器变量(数组、结构),MATLAB具有等效的foreach-like构造:arrayfun、structfun。
这将适用于长度超过单个字符的c2内容,并且它不需要作为stardt的解决方案的大型repmat操作。然而,当涉及到c2只有几个重复值的长数组时,我确实有疑问,但我猜对于大多数算法来说,这将是一个困难的情况。如果你在这种情况下,你可能需要看看unique的额外输出,或者编写你自己的unique的替代品(即编写for循环,最好是用编译语言/MEX)。
https://stackoverflow.com/questions/8024639
复制相似问题