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)
其中n
是CLUSTER
列设置为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 - 迭代计算的迭代的主要内容,如果未能解决你的问题,请参考以下文章