我有一个像这样的矩阵:
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点有它们的原始数据。
我一直在找到列的每两个元素的差异并存储它们。我的代码没有给我所需的输出。 有人可以帮忙吗? 提前谢谢。
答案 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
。