我有一个这样的矩阵:
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)点合并到它们的平均位置(根据阈值差<2),而8和9点具有其原始数据。
我被困在寻找列中每两个元素的差异并存储它们。我的代码没有给我想要的输出。有人能帮帮忙吗?提前谢谢。
发布于 2015-04-29 20:34:28
使用矢量化表示法可以大大简化这一过程。例如,您可以这样做
fd(:,1) - fd(:,2)
来获得第1列和第2列之间的差异(或者等效于diff(fd(:,[1 2]), 1, 2)
)。您可以使用pdist
使其更易于阅读和调试,但是如果您只有三列,那么可能会遇到更多麻烦。
我怀疑您的第一个问题与diff
的第三个参数有关。如果你使用diff(X, 1, 1)
,它将在方向1上做一阶差分,也就是说在相邻行之间(向下)。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
。
https://stackoverflow.com/questions/29943545
复制相似问题