Python - 迭代计算的迭代

Posted

技术标签:

【中文标题】Python - 迭代计算的迭代【英文标题】:Python - Iteration over iteration calculation 【发布时间】:2022-01-21 00:16:15 【问题描述】:

早上好。 我有一个包含近 130 万行的数据库(月球陨石坑数据库),我想对较大陨石坑内的陨石坑进行聚类。为此,我将数据库从大到小排序,而不是在其他数据库上迭代更大,以计算位置之间的距离在直径内。问题是这个计算每个陨石坑大约需要 50 秒,因此计算所有 DB 需要几个月的时间。我尝试了一些替代技术,如 Dask、Multiprocessing,但没有奏效。任何人都可以帮助我。

cluster = 1
for i in range(len(craters_diam)):
    start2 = datetime.now()
    if craters_diam.loc[i, 'CLUSTER'] == 0:
        craters_diam.loc[i, 'CLUSTER'] = cluster
        lat1 = craters_diam.loc[i, 'LAT_CIRC_IMG']
        lon1 = craters_diam.loc[i, 'LON_CIRC_IMG']
        diam = craters_diam.loc[i, 'DIAM_CIRC_IMG']
        for j in range(i+1, len(craters_diam)):
            if craters_diam.loc[j, 'CLUSTER'] == 0:
                lat2 = craters_diam.loc[j, 'LAT_CIRC_IMG']
                lon2 = craters_diam.loc[j, 'LON_CIRC_IMG']
                dist = distance(lat1, lat2, lon1, lon2)
                if dist <= diam/2:
                    craters_diam.loc[j, 'CLUSTER'] = cluster
        cluster += 1
    print(datetime.now() - start2)
print(datetime.now() - start)

球面几何中的距离函数计算。

如果有人知道一个聪明(更快)的方法,谢谢!!!

【问题讨论】:

【参考方案1】:

计算速度很慢,因为算法的复杂性是二次方O(n * n) 其中nCLUSTER 列设置为0 的项目数。

首先,有很多更快的算法可以进行聚类。你的算法看起来像一个简化的DBSCAN。例如,一个著名的是k-Means,它假设您大约知道集群的数量(这里不是这种情况)。当您不知道集群数量时,另一种解决方案是使用Mean-Shift Clustering,尽管我不确定它是否适用于您的特定数据集。

为了有效地获取靠近目标的相邻点,您可以使用k-d tree 结构。在 2D 中,您可以使用quad-tree,它更容易实现,而且通常速度更快。这种结构可以将算法的复杂度从O(n * n) 降低到O(n log n)。这个想法是添加树中的所有点,然后为每个点寻找关闭点。在您的情况下,我希望这会快 3~4 个数量级。在 Python 中执行此操作的一种简单方法是使用 Scipy implementation of k-d tree。 Scipy 实现不是很快,但这应该足以让您的算法大大加快(尽管使用起来有点复杂)。一种更快的方法是用本地语言实现,并使用多线程并行执行计算。

请注意,遍历 Pandas 数据帧通常是known to be very slow,您应该尽可能使用矢量化函数。如果无法做到这一点,您可以使用 Numpy 或使用 Numba 或 Cython 编写自己的函数。

【讨论】:

以上是关于Python - 迭代计算的迭代的主要内容,如果未能解决你的问题,请参考以下文章

Python之Gauss-Seidel迭代计算

python 计算Python可迭代窗口的总和

Python迭代不同大小的数组

python--生成器和迭代器

Python迭代器(Iterator)

Python 振动分析 迭代法计算高阶特征值及特征向量