MATLAB中利用标签向量合并矩阵

MATLAB中利用标签向量合并矩阵,matlab,Matlab,我有以下数据 长度为n1的行向量idx1 m×n1矩阵A1 长度为n2的行向量idx2 m×n2矩阵A2 行向量idx1和idx2分别标记A1和A2的列。本质上,我想根据idx1和idx2中的标签合并A1和A2的列。我认为给出一些我已经有的代码来完成这项工作是最容易的 idx = union(idx1,idx2); A = zeros(size(A1,1),length(idx)); for i = 1:length(idx) j1 = find(idx1 == idx(i),1);

我有以下数据

  • 长度为n1的行向量idx1
  • m×n1矩阵A1
  • 长度为n2的行向量idx2
  • m×n2矩阵A2
行向量idx1和idx2分别标记A1和A2的列。本质上,我想根据idx1和idx2中的标签合并A1和A2的列。我认为给出一些我已经有的代码来完成这项工作是最容易的

idx = union(idx1,idx2);
A = zeros(size(A1,1),length(idx));
for i = 1:length(idx)
    j1 = find(idx1 == idx(i),1);
    if ~isempty(j1)
        A(:,i) = A(:,i) + A1(:,j1);
    end
    j2 = find(idx2 == idx(i),2);
    if ~isempty(j2)
        A(:,i) = A(:,i) + A2(:,j2);
    end
end

现在,我的问题是,我想有效地执行这个操作,有时是在稀疏矩阵上。有没有比我所拥有的更快的方法?如果A1和A2稀疏,答案是否会改变?

您可以使用整个数组执行加法(代价是调用两次
ismember

idx = union(idx1,idx2);
A = zeros(size(A1,1),length(idx));

[~,loc1] = ismember(idx1,idx);
[~,loc2] = ismember(idx2,idx);

A(:,loc1) = A(:,loc1) + A1;
A(:,loc2) = A(:,loc2) + A2;

如果
idx1
idx2
包含整数值,则可以使用
sparse
函数进行求和:

[ii1 jj1] = ndgrid(1:m, idx1);
[ii2 jj2] = ndgrid(1:m, idx2);
A = sparse([ii1 ii2],[jj1 jj2],[A1 A2]); %// do the sum for matching indices
A = A(:,union(idx1, idx2)); %// result in sparse form
A = full(A); %// optional

这难道不需要对idx1和idx2进行排序吗?@bdecaf:no-使用
loc
output参数可以解决这个问题。感谢您的输入!但我发现这比我的代码慢40%左右。在R2009b中,我在一个小示例中使用tic/toc对这两种方法进行了1000次重复,我的代码运行时间为0.1295s,而您的代码运行时间为0.1833s。在运行了更多的测试之后,当A1和A2稀疏时,这个版本似乎可以快一点。@Stirling:如果索引被排序,您可以调用
ismembc
而不是ismember来跳过两个额外的排序步骤。我们是否应该假设
idx1
没有重复值,而
idx2
也有重复值?否则我认为您的代码不起作用我们可以假设idx1和idx2是正整数的排序向量,不包含重复值。