【问题标题】:Calculating difference between both adjacent and non-adjacent pairs using multiple index vectors使用多个索引向量计算相邻和非相邻对之间的差异
【发布时间】:2015-08-22 17:48:09
【问题描述】:

我有三个数值向量,其中包含位置值 (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 个该类型的实例存在。

类型并不总是只有 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

在这种情况下,脚本可以完美运行:

【问题讨论】:

  • 至少在最近的 matlab 版本中,我希望使用两个循环的解决方案是最快的。
  • 这种情况下的预期输出是什么?我不明白您想如何将输出放入一个矩阵中。
  • 那么对于ind 的每个值以及与type 重合的pos 的相应值,您是否希望找到所有可能的差异组合?我仍然无法理解预期的输出是什么。
  • 并非所有组合。它是从左到右依次完成的。任何给定类型的第一个值与其右侧相同类型的下一个值配对,依此类推。 Pos 将始终针对每个索引进行排序。

标签: arrays matlab indexing


【解决方案1】:

至少为了创建输出矩阵需要一个循环:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-21
    • 1970-01-01
    相关资源
    最近更新 更多