我想分割这些数据,
ID x y
1 2.5 3.5
1 85.1 74.1
2 2.6 3.4
2 86.0 69.8
3 25.8 32.9
3 84.4 68.2
4 2.8 3.2
4 24.1 31.8
4 83.2 67.4
我能够和他们的伴侣配对,
ID x y ID x y
1 2.5 3.5 1 85.1 74.1
2 2.6 3.4 2 86.0 69.8
3 25.8 32.9
4 24.1 31.8
但是,您会注意到ID 4中的某些新行被放错了位置,因为它只是被添加到接下来的几行中。我想适当地拆分它们,而不必使用我已经在使用的复杂逻辑...有人可以给我一个算法或想法吗?
它看起来应该像
ID x y ID x y ID x y
1 2.5 3.5 1 85.1 74.1 3 25.8 32.9
2 2.6 3.4 2 86.0 69.8 4 24.1 31.8
4 2.8 3.2 3 84.4 68.2
4 83.2 67.4
最佳答案
看来您的问题确实与聚类有关,并且ID列与确定哪个点对应于哪个点无关。
常见的算法是k-means clustering。但是,您的问题意味着您不预先知道群集的数量。这使事情变得复杂,并且在StackOverflow上已经有很多关于此问题的问题:
不幸的是,对此没有“正确”的解决方案。一个特定问题中的两个群集实际上可以视为另一个问题中的一个群集。这就是为什么您必须自己决定的原因。
但是,如果您正在寻找简单的东西(可能不准确),则可以使用欧几里得距离作为度量。计算点之间的距离(例如,使用
pdist
),并对距离低于特定阈值的点进行分组。例
%// Sample input
A = [1, 2.5, 3.5;
1, 85.1, 74.1;
2, 2.6, 3.4;
2, 86.0, 69.8;
3, 25.8, 32.9;
3, 84.4, 68.2;
4, 2.8, 3.2;
4, 24.1, 31.8;
4, 83.2, 67.4];
%// Cluster points
pairs = nchoosek(1:size(A, 1), 2); %// Rows of pairs
d = sqrt(sum((A(pairs(:, 1), :) - A(pairs(:, 2), :)) .^ 2, 2)); %// d = pdist(A)
thr = d < 10; %// Distances below threshold
kk = 1;
idx = 1:size(A, 1);
C = cell(size(idx)); %// Preallocate memory
while any(idx)
x = unique(pairs(pairs(:, 1) == find(idx, 1) & thr, :));
C{kk} = A(x, :);
idx(x) = 0; %// Remove indices from list
kk = kk + 1;
end
C = C(~cellfun(@isempty, C)); %// Remove empty cells
结果是一个单元格数组
C
,每个单元格代表一个集群:C{1} =
1.0000 2.5000 3.5000
2.0000 2.6000 3.4000
4.0000 2.8000 3.2000
C{2} =
1.0000 85.1000 74.1000
2.0000 86.0000 69.8000
3.0000 84.4000 68.2000
4.0000 83.2000 67.4000
C{3} =
3.0000 25.8000 32.9000
4.0000 24.1000 31.8000
注意,这种简单的方法具有将簇半径限制为阈值的缺陷。但是,您需要一个简单的解决方案,因此请记住,随着向该算法添加更多“集群逻辑”,该解决方案会变得复杂。
关于c++ - 知道其通用ID的拆分数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14458526/