1

我有以下两个矩阵

c=[1 0 1.05 
   1 3 2.05
   1 6 2.52
   1 9 0.88
   2 0 2.58
   2 3 0.53
   2 6 3.69
   2 9 0.18
   3 0 3.22
   3 3 1.88
   3 6 3.98]

f=[1 6 3.9
   1 9 9.1
   1 12 9
   2 0 0.3
   2 3 0.9
   2 6 1.2
   2 9 2.5
   3 0 2.7]

最终的矩阵应该是

n=[1 6 2.52 3.9
   1 9 0.88 9.1
   2 0 2.58 0.3
   2 3 0.53 0.9
   2 6 3.69 1.2
   2 9 0.18 2.5
   3 0 3.22 2.7]

结果,我使用的代码仅给出了前一个矩阵 [n] 的最后一行。

for j=1
  for i=1:rs1
     for k=1
          for l=1:rs2
               if f(i,j)==c(l,k) && f(i,j+1)==c(l,k+1)                 
                  n=[f(i,j),f(i,j+1),f(i,j+2), c(l,k+2)];
               end
          end
      end 
   end
 end

谁可以帮我这个事?还有更简单的吗?

提前致谢

4

5 回答 5

1

您应该学习使用集合操作并尽可能避免循环。这里intersect可能非常有用:

[u, idx_c, idx_f] = intersect(c(:, 1:2) , f(:, 1:2), 'rows');
n = [c(idx_c, :), f(idx_f, end)];

说明:通过指定'rows'标志,在和intersect中找到共同的行,它们的索引分别在和中给出。使用向量下标提取矩阵。cfidx_cidx_fn

例子

让我们使用您问题中的示例:

c = [1 0 1.05;
     1 3 2.05
     1 6 2.52
     1 9 0.88
     2 0 2.58
     2 3 0.53
     2 6 3.69
     2 9 0.18
     3 0 3.22
     3 3 1.88
     3 6 3.98];

f = [1 6 3.9
     1 9 9.1
     1 12 9
     2 0 0.3
     2 3 0.9
     2 6 1.2
     2 9 2.5
     3 0 2.7];

[u, idx_c, idx_f] = intersect(c(:, 1:2) , f(:, 1:2), 'rows');
n = [c(idx_c, :), f(idx_f, end)];

这应该会产生预期的结果:

n =
    1.0000    6.0000    2.5200    3.9000
    1.0000    9.0000    0.8800    9.1000
    2.0000         0    2.5800    0.3000
    2.0000    3.0000    0.5300    0.9000
    2.0000    6.0000    3.6900    1.2000
    2.0000    9.0000    0.1800    2.5000
    3.0000         0    3.2200    2.7000
于 2013-03-28T00:14:56.090 回答
1

如果您坚持在循环中执行此操作,则需要n根据您正在使用的循环计数器提供适当的维度,或者将其连接到每次迭代的自身(对于大矩阵,这可能非常慢)。例如,写作:

for j=1
  for i=1:rs1
    for k=1
      for l=1:rs2
           m=m+1;
           if f(i,j)==c(l,k) && f(i,j+1)==c(l,k+1)                 
              n(m,:)=[f(i,j),f(i,j+1),f(i,j+2), c(l,k+2)];
           end
       end
    end 
  end
end

当循环达到计数器值时,会将 for 数字保存到第 m 行m

但是,请注意,这也可以在没有嵌套循环和 if 条件的情况下以向量化的方式完成。例如,代替if f(i,j)==c(l,k)...您可以使用的条件ismember等...

于 2013-03-24T21:35:45.567 回答
1

您可以通过同时比较第一列和第二列来减少循环次数,然后使用“all”函数仅在它们都匹配时折叠值。以下代码段复制了您提供的“n”数组。

n = [];
for r1 = 1:size(c, 1)
    for r2 = 1:size(f,1)
        if all(c(r1, [1 2]) == f(r2, [1 2]))
            n(end+1, 1:4) = [c(r1,:) f(r2,3)];
        end
    end    
end
于 2013-03-24T21:44:35.573 回答
1

根据这个关于 Mathworks 支持的答案,您可以使用统计工具箱中的连接,特别是在您的情况下,内连接。

不幸的是,我无法访问我的带有 matlab 的计算机,但试一试,让我们知道它是如何工作的。

于 2013-03-24T20:55:44.607 回答
0

根本没有任何 for 循环怎么样(除了在本机代码中)

mf = size(f,1);
mc = size(c,1);
a = repmat(c(:,1:2),1,mf);
b = repmat(reshape((f(:,1:2))',1,[]),mc,1);
match = a == b;
match = match(:, 1 : 2 : 2*mf) & match(:, 2 : 2 : 2*mf);

crows = nonzeros(diag(1:mc) * match);
frows = nonzeros(match * diag(1:mf));

n = [c(crows,:),f(frows,3)]
于 2013-03-26T18:37:55.760 回答