Performance 根据坐标对点进行分类
Performance 根据坐标对点进行分类,performance,matlab,sorting,grouping,classification,Performance,Matlab,Sorting,Grouping,Classification,A是三维(x,y,z)中多个点的坐标矩阵。例如: A=[1.6 2.13 3;1.2 2.36 5;1.4 2.4 6;1.01 2.21 9] A= 1.6 2.13 3.0 1.2 2.36 5.0 1.4 2.40 6.0 1.01 2.21 9.0 我正在寻找一种“有效”的解决方案,将第二列(Y)的点分组为阈值为0.09的“三”组。指: GroupNumber=3; 阈值=(最大(A(:,2))-min(A(:,2))/GroupNumbe
A
是三维(x,y,z)中多个点的坐标矩阵。例如:
A=[1.6 2.13 3;1.2 2.36 5;1.4 2.4 6;1.01 2.21 9]
A=
1.6 2.13 3.0
1.2 2.36 5.0
1.4 2.40 6.0
1.01 2.21 9.0
我正在寻找一种“有效”的解决方案,将第二列(Y
)的点分组为阈值为0.09
的“三”组。指:
GroupNumber=3;
阈值=(最大(A(:,2))-min(A(:,2))/GroupNumber代码>
组{1}=
1.60 2.13 3.0
1.01 2.21 9.00
群{2}=
1.2 2.36 5.0
群{3}=
1.4 2.40 6.0
任何帮助都将不胜感激 我现在无法访问MATLAB,但大致上是这样的:
你可以得到第一组,如下所示
A= [1.6 2.13 3; 1.2 2.36 5; 1.4 2.4 6; 1.01 2.21 9]
B = A(:,2);
mean = (max(B)-min(B))/3;
C = B - min(B);
Group1 = A(C<mean,:)
然后重复,直到为空(A)==true
。不过,有许多优化是可能的
编辑:
A= [1.6 2.13 3; 1.2 2.36 5; 1.4 2.4 6; 1.01 2.21 9]
while ~isempty(A)
B = A(:,2);
mean1 = (max(B)-min(B))/3;
C = B - min(B);
Group1 = A(C<mean1,:)
A = A(C>=mean1,:)
if size(A,1)==1
break;
end
end
方法#1
对于A
中有相当多的行,您可能更喜欢矢量化解决方案-
GroupNumber = 3;
sorted_A = sortrows(A,2);
sorted_A_col2 = sorted_A(:,2);
limits = sorted_A_col2 + (max(sorted_A_col2) - sorted_A_col2)./GroupNumber;
matches = bsxfun(@le,sorted_A_col2,limits.'); %//'
[~,col_ind] = max(matches,[],2);
groups = arrayfun(@(x) sorted_A(col_ind == x,:), unique(col_ind),'Uniform',0);
使用给定输入的celldisp(组)
显示输出-
groups{1} =
1.6000 2.1300 3.0000
1.0100 2.2100 9.0000
groups{2} =
1.2000 2.3600 5.0000
groups{3} =
1.4000 2.4000 6.0000
进近#2
对于包含大量行的A
,您很可能没有剩余的内存来处理bsxfun
,并且您将被迫对这种情况使用某种循环方法,因此效率不高。以下可能是其中之一-
GroupNumber = 3;
sorted_A = sortrows(A,2);
sorted_A_col2 = sorted_A(:,2);
limits = sorted_A_col2 + (max(sorted_A_col2) - sorted_A_col2)./GroupNumber;
nrows = size(A,1);
prev_matches = false(nrows,1);
groups = cell(nrows,1);
for iter = 1:nrows
curr_matches = sorted_A_col2<=limits(iter);
groups{iter} = sorted_A(xor(curr_matches,prev_matches),:);
prev_matches = curr_matches;
end
groups = groups(~cellfun('isempty',groups));
GroupNumber=3;
排序后的A=sortrows(A,2);
排序的列2=排序的列(:,2);
限制=排序的列2+(最大值(排序的列2)-排序的列2)。/GroupNumber;
nrows=尺寸(A,1);
上一次匹配=错误(nrows,1);
组=细胞(nrows,1);
对于iter=1:nrows
curr\u matches=sorted\u A\u col2生成一大组数据:
A = 100 * rand(2000000,3);
tic
GroupNumber = 100 ;` `% in hundred group
Threshold = (length(A))/GroupNumber ;
A = sortrows(A,2);
Group = cell(GroupNumber,1);`
for i = 1 : GroupNumber;
if i == 1
Group{i} = A(1:ceil(Threshold),:);
elseif i > 1 && i~= GroupNumber
if ceil((i-1)*Threshold) == ceil(Threshold)
bottum = ceil((i-1)*Threshold)+1;
else
end
top=ceil(i*Threshold);
Group{i} = A(bottum:top,:);
elseif i == GroupNumber
bottum = ceil((i-1)*Threshold);
if ceil((i-1)*Threshold)<=ceil(i*Threshold) && ceil((i-1)*Threshold)>top
Group{i} = A(bottum:end,:);
elseif ceil((i-1)*Threshold)<=top
Group{i} = A(bottum+1:end,:);
end
end
end
toc
运行时间为0.000010
秒。为什么2.36和2.40不在同一组中?您可以使用k-最近邻分类法轻松获得该结果。@NKN感谢您的回复。你是对的。问题已经修改。你的意思是0.09
对吗?谢谢你,伙计。不过,让我们暂时把这个问题留待讨论,以获得更多可能的答案。感谢Divakar一如既往地抽出您的时间!尽管建议的方法看起来不错,但它会在bsxfun
行对大量数据(如2000000点)产生错误:使用bsxfun时出错;内存不足。为您的选项键入帮助记忆
我是用下面写的另一种方式做的。顺便说一句,如果你纠正我的话,我会很感激的;)@对不起!出于某种原因,这件事离开了我的脑海,但我很高兴又回到了它。那么,请查看编辑后的代码?很抱歉我的回复太晚,您的代码似乎组织得更好,效率更高。我选择了一个正确的答案。Thanks@Divakar我知道最后提出的方法不是一个优化的解决方案。但是,你认为这是一个可以接受的答案吗?不要认为这会给你正确的结果。对于验证,您可以尝试使用较小的a
如a=rand(20,3)
并使用GroupNumber=3
并与我列出的两种方法中的任何一种进行比较?
GroupNumber = 3;
sorted_A = sortrows(A,2);
sorted_A_col2 = sorted_A(:,2);
limits = sorted_A_col2 + (max(sorted_A_col2) - sorted_A_col2)./GroupNumber;
nrows = size(A,1);
prev_matches = false(nrows,1);
groups = cell(nrows,1);
for iter = 1:nrows
curr_matches = sorted_A_col2<=limits(iter);
groups{iter} = sorted_A(xor(curr_matches,prev_matches),:);
prev_matches = curr_matches;
end
groups = groups(~cellfun('isempty',groups));
A = 100 * rand(2000000,3);
tic
GroupNumber = 100 ;` `% in hundred group
Threshold = (length(A))/GroupNumber ;
A = sortrows(A,2);
Group = cell(GroupNumber,1);`
for i = 1 : GroupNumber;
if i == 1
Group{i} = A(1:ceil(Threshold),:);
elseif i > 1 && i~= GroupNumber
if ceil((i-1)*Threshold) == ceil(Threshold)
bottum = ceil((i-1)*Threshold)+1;
else
end
top=ceil(i*Threshold);
Group{i} = A(bottum:top,:);
elseif i == GroupNumber
bottum = ceil((i-1)*Threshold);
if ceil((i-1)*Threshold)<=ceil(i*Threshold) && ceil((i-1)*Threshold)>top
Group{i} = A(bottum:end,:);
elseif ceil((i-1)*Threshold)<=top
Group{i} = A(bottum+1:end,:);
end
end
end
toc
A = [1.6 2.13 3; 1.2 2.36 5; 1.4 2.4 6; 1.01 2.21 9];
GroupNumber = 3;
Group{1} =
1.6000 2.1300 3.0000
1.0100 2.2100 9.0000
Group{2} =
1.2000 2.3600 5.0000
Group{3} =
1.4000 2.4000 6.0000