我有三个数字向量,它们包含位置值(pos
)、类别(type
)和索引(ind
),它们是这样的一般形式:
pos =
2 4 5 11 1 5 8 11 12 20
type =
1 2 1 2 1 1 2 1 2 3
ind =
1 1 1 1 2 2 2 2 2 2
我想要计算pos中持有的值之间的差异,但只计算相同类型之间的差异,并且仅限于每个索引。使用上面的示例:
( ind = 1 )
The difference(s) between type 1 positions = 3 (5-2).
The difference(s) between type 2 positions = 7 (11-4).
在任何索引中存在超过两个给定类型的实例的情况下,从左到右依次计算差异,如下所示:
时ind = 2
The difference(s) between type 1 positions = 4 (5-1), 6 (11-5).
The difference(s) between type 2 positions = 4 (12-8).
即使索引2包含类型'3',也不会计算差异,因为只有一个这种类型的实例存在。
类型并不总是只有1、2或3。
理想情况下,期望的输出是矩阵,它包含与length(unique(type))
相同的列数,行包含为该类型计算的所有差异。输出不需要按索引分开,只有实际的计算需要。在这种情况下,有三种唯一的类型,因此输出将是(仅为清晰性添加标签):
Type 1 Type 2 Type 3
3 7 0
4 4 0
6 0 0
任何空条目都可以用零填充。
是否有一种简洁或快速的方式来做到这一点?
编辑
编辑2:
附加输入/输出示例。
pos = [1 15 89 120 204 209 8 43 190 304]
type = [1 1 1 2 2 1 2 3 2 3]
ind = [1 1 1 1 1 1 2 2 2 2]
期望产出:
Type 1 Type 2 Type 3
14 84 261
74 182 0
120 0 0
在这种情况下,脚本工作得很好:
发布于 2015-08-22 19:19:35
至少在创建输出矩阵时需要循环:
pos = [2 4 5 11 1 5 8 11 12 20]
type = [1 2 1 2 1 1 2 1 2 3]
ind = [1 1 1 1 2 2 2 2 2 2]
%// get unique combinations of type and ind
[a,~,subs] = unique( [type(:) ind(:)] , 'rows')
%// create differences
%// output is cell array according to a
temp = accumarray(subs,1:numel(subs),[],@(x) {abs(diff(pos(x(end:-1:1))))} )
%// creating output matrix
for ii = 1:max(a(:,1)) %// iterating over types
vals = [temp{ a(:,1) == ii }]; %// differences for each type
out(1:numel(vals),ii) = vals;
end
out =
3 7 0
4 4 0
6 0 0
如果它不适用于实际数据,您可能需要unique(...,'rows','stable')
和'stable' accumarray。
上面的解决方案根据系统.给出了不同的结果。
代码在不同的机器上给出不同结果的唯一原因是,accumarray
并不像上面提到的那样是“稳定的”。在一些非常罕见的情况下,它可能会返回不可预测的结果。因此,请尝试以下几点:
pos = [2 4 5 11 1 5 8 11 12 20]
type = [1 2 1 2 1 1 2 1 2 3]
ind = [1 1 1 1 2 2 2 2 2 2]
%// get unique combinations of type and ind
[a,~,subs] = unique( [type(:) ind(:)] , 'rows')
%// take care of unstable accumarray
[~, I] = sort(subs);
pos = pos(I);
subs = subs(I,:);
%// create differences
%// output is cell array according to a
temp = accumarray(subs,1:numel(subs),[],@(x) {abs(diff(pos(x(end:-1:1))))} )
%// creating output matrix
for ii = 1:max(a(:,1)) %// iterating over types
vals = [temp{ a(:,1) == ii }]; %// differences for each type
out(1:numel(vals),ii) = vals;
end
out =
3 7 0
4 4 0
6 0 0
https://stackoverflow.com/questions/32159050
复制相似问题