矩阵

时间:2015-04-29 12:18:29

标签: matlab merge diff

我有一个像这样的矩阵:

fd = 

x   y   z
2   5   10
2   6   10
3   5   11
3   9   11
4   3   11
4   9   12
5   4   12
5   7   13
6   1   13
6   5   13

我的问题有两部分:

1)我想计算一列中每两个元素的差异。 所以我尝试了以下代码:

for i= 1:10

n=10-i;

for j=1:n

    sdiff1 = diff([fd(i,1); fd(i+j,1)],1,1);
    sdiff2 = diff([fd(i,2); fd(i+j,2)],1,1);
    sdiff3 = diff([fd(i,3); fd(i+j,3)],1,1);

end

end

我想要所有的差异,例如:

  x1-x2, x1-x3, x1-x4....x1-x10
  x2-x3,  x2-x4.....x2-x10
  .
  .
  .
  .
  .
  x9-x10

y和z值差异相同

然后所有值都应存储在sdiff1,sdiff2和sdiff3

2)接下来我想要的是相同的z值,我想保留原始数据点。对于不同的z值,我想合并那些彼此接近的点。我的意思是接近,

if abs(sdiff3)== 0
keep the original data

for abs(sdiff3) > 1
if abs(sdiff1) < 2 & abs(sdiff2) < 2

然后我需要平均值x,平均值y和平均值z。

所以我尝试了整个程序:

for i= 1:10

    n=10-i;

    for j=1:n

    sdiff1 = diff([fd(i,1); fd(i+j,1)],1,1);
    sdiff2 = diff([fd(i,2); fd(i+j,2)],1,1);
    sdiff3 = diff([fd(i,3); fd(i+j,3)],1,1);

       if (abs(sdiff3(:,1)))> 1


               continue

    mask1 = (abs(sdiff1(:,1)) < 2) & (abs(sdiff2(:,1)) < 2) & (abs(sdiff3:,1)) > 1);
    subs1 = cumsum(~mask1);

    xmean1 = accumarray(subs1,fd(:,1),[],@mean);
    ymean1 = accumarray(subs1,fd(:,2),[],@mean);
    zmean1 = accumarray(subs1,fd(:,3),[],@mean);
    fd = [xmean1(subs1) ymean1(subs1) zmean1(subs1)];


       end 
    end

end

我的最终输出应该是:

2.5   5   10.5
3.5   9   11.5
5     4   12
5     7   13
6     1   13

其中,(1,2,3),(4,6),(5,7,10)点合并到它们的平均位置(根据阈值差<&lt; 2),而第8和第9点有它们的原始数据。

我一直在找到列的每两个元素的差异并存储它们。我的代码没有给我所需的输出。 有人可以帮忙吗? 提前谢谢。

1 个答案:

答案 0 :(得分:0)

使用矢量化符号可以大大简化这一点。你可以做例如

fd(:,1) - fd(:,2)

获取第1列和第2列之间的差异(或等效diff(fd(:,[1 2]), 1, 2))。您可以使用pdist来更优雅/更难阅读和调试,但如果您只有三列,则可能比它的价值更麻烦。

我怀疑你的第一个问题是diff的第三个问题。如果你使用diff(X, 1, 1),它将在方向1上执行第一阶diff,也就是说在相邻行之间(向下)。 diff(X, 1, 2)将在相邻列(向右)之间执行此操作,这是您想要的。 Matlab使用与电子表格相反的约定,因为它首先对行进行索引,然后是列。

一旦你有了差异,你就可以测试元素:

thesame = find(sdiff3 < 2); % for example

这将产生sdiff3的行索引的向量,其中值小于2.然后你可以使用

fd(thesame,:)

在这些索引中选择fd的元素。要删除匹配的行,您将执行相反的测试

notthesame = find(sdiff > 2);

找到要保留的那些,然后将它们提取到一个新数组

keepers = fd(notthesame,:);

这些不会为您提供确切的解决方案,但它会让您走上正确的轨道。有关这些命令的语法和许多示例,您可以运行,例如在命令窗口中doc diff