微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

非常大的数据集中的成对距离

如何解决非常大的数据集中的成对距离

我有一个大约 [5000000 x 6] 的数组,我只需要选择彼此相距一定距离的点(行)。

想法应该是:

从数据数组的第一行开始 new_array

将 new_array 与数据数组中的第二行进行比较

如果它们之间的 pdist 是 > tol,则将行附加到 new_array

将 new_array 与数据数组中的第三行进行比较

等等...

一个问题是 RAM 大小。即使在 pdist 中,我也无法一次比较所有行。

所以我一直在考虑将数据集拆分成较小的数据集,但后来我不知道如何检索数据集中行的索引信息。

我尝试过 scipy cdist、scipy euclidean、sklearn euclidean_distances、sklearn paired_distances,下面的代码是我能得到的最快的。起初它很快,但在 40k 循环之后它变得非常慢。

xyTotal=np.random.random([5000000,6])
tol=0.5
for i,z in enumerate(xyTotal):
    if (pdist(np.vstack([np.array(ng),z]))>tol).all():
        ng.append(z)

对这个问题有什么建议吗?

编辑

ktree = BallTree(xyTotal,leaf_size=40,metric='euclidean')
btsem=[]
for i,j in enumerate(xyTotal):
    ktree.query_radius(j.reshape(1,-1),r=tol,return_distance=True)
    if (ktree.query_radius(j.reshape(1,count_only=True))==1:
        btsem.append(j)

这很快,但我只挑选异常值。当我到达靠近另一个点的点(即在一个小集群中)时,我不知道只选择一个点并留下其他点,因为我将获得集群中所有点的相同指标(它们都有彼此之间的距离相同)

解决方法

计算速度很慢,因为算法的复杂度是二次的O(k * n * n) 其中 n 是 len(xyTotal)k 是条件成立的概率.因此,假设 k=0.1n=5000000,运行时间将是巨大的(可能需要数小时的计算)。

希望您可以编写一个在 O(n * log(n)) 时间内运行的更好的实现。然而,这很难实现。您需要在kd树中添加您的ng点,然后您可以搜索最近邻并检查与当前点的距离大于{{ 1}}。

请注意,您可以找到实现 k-d 树的 Python 模块,并且 SciPy 文档提供了用纯 Python 编写的 an example of implementation(因此可能效率不高)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。