我提出的最后一个问题涉及如何通过x坐标来分组数据。解决方案简单而优雅,我很惭愧,我没有看到它。这个问题可能更难(或者我可能只是盲目)。
我从大约140000个数据点开始,将它们分成70个沿x轴等间隔的组,然后取每个组的平均位置(x_avg,y_avg)并绘制它们;出现了一条漂亮的曲线不幸的是有两个问题。首先,边缘的填充量远小于图形的中心;其次,某些领域的变化比其他领域更多,因此需要更好的解决方案。
因此,我有两个具体问题和一般性邀请来提出建议:
matlab是否有内置的方法将矩阵拆分为固定数量的较小的matricies或固定大小的较小的matricies?
是否存在算法(或matlab函数,但我发现不太可能)来确定更精细地区分感兴趣区域所需的边界?
更一般地说,是否有更好的方法将成千上万的数据点凝聚成一个整洁的趋势?
答案 0 :(得分:2)
听起来你想要根据x值的密度使用大小不一的垃圾箱。我认为您仍然可以在上一篇文章的答案中使用HISTC函数,但您只需要给它一组不同的边。
我不知道这是否是你想要的,但是这里有一个建议:不是将x轴分成70个等距组,而是将排序的x数据分成70个相等的组并确定边缘值。我认为这段代码应该有效:
% Start by assuming x and y are vectors of data:
nBins = 70;
nValues = length(x);
[xsort,index] = sort(x); % Sort x in ascending order
ysort = y(index); % Sort y the same way as x
binEdges = [xsort(1:ceil(nValues/nBins):nValues) xsort(nValues)+1];
% Bin the data and get the averages as in previous post (using ysort instead of y):
[h,whichBin] = histc(xsort,binEdges);
for i = 1:nBins
flagBinMembers = (whichBin == i);
binMembers = ysort(flagBinMembers);
binMean(i) = mean(binMembers);
end
这应该为您提供尺寸与数据密度不同的垃圾箱。
更新:另一个版本......
这是我在发表一些评论后提出的另一个想法。使用此代码,您可以为x中的相邻数据点之间的差异设置阈值(maxDelta)。任何与其较大邻居相差大于或等于maxDelta的x值都被强制放在他们自己的bin中(所有这些都是他们的寂寞)。您仍然为nBins选择一个值,但当展开点降级到自己的箱子时,最终的箱数将大于此值。
% Start by assuming x and y are vectors of data:
maxDelta = 10; % Or whatever suits your data set!
nBins = 70;
nValues = length(x);
[xsort,index] = sort(x); % Sort x in ascending order
ysort = y(index); % Sort y the same way as x
% Create bin edges:
edgeIndex = false(1,nValues);
edgeIndex(1:ceil(nValues/nBins):nValues) = true;
edgeIndex = edgeIndex | ([0 diff(xsort)] >= maxDelta);
nBins = sum(edgeIndex);
binEdges = [xsort(edgeIndex) xsort(nValues)+1];
% Bin the data and get the y averages:
[h,whichBin] = histc(xsort,binEdges);
for i = 1:nBins
flagBinMembers = (whichBin == i);
binMembers = ysort(flagBinMembers);
binMean(i) = mean(binMembers);
end
我在几个小样本数据集上测试了它,它似乎做了它应该做的事情。希望它也适用于您的数据集,无论它包含什么! =)
答案 1 :(得分:1)
我从来没有使用过matlab,但是从查看你之前的问题开始,我怀疑你是在寻找Kdtree或变体的内容。
澄清:由于似乎有一些混淆,我认为伪代码示例是有序的。
// Some of this shamelessly borrowed from the wikipedia article
function kdtree(points, lower_bound, upper_bound) {
// lower_bound and upper_bound are the boundaries of your bucket
if(points is empty) {
return nil
}
// It's a trivial exercise to control the minimum size of a partition as well
else {
// Sort the points list and choose the median element
select median from points.x
node.location = median;
node.left = kdtree(select from points where lower_bound < points.x <= median, lower_bound, median);
node.right = kdtree(select from points where median < points.x <= upper_bound, median, upper_bound);
return node
}
}
kdtree(points, -inf, inf)
// or alternatively
kdtree(points, min(points.x), max(points.x))