Python-迭代计算



早上好。我有一个近130万行的DB(月球陨石坑DB(,我想把更大的陨石坑内的陨石坑聚类。为了做到这一点,我将DB从大到小排序,然后将较大的值迭代到其他值,以计算直径内位置之间的距离。问题是,每个弹坑的计算大约需要50秒,因此计算所有DB需要几个月的时间。我尝试了一些替代技术,如Dask、多处理器,但没有成功。任何人都可以帮助我。

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)

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

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

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

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

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

请注意,在Pandas数据帧上迭代通常是非常慢的,并且应该尽可能多地使用矢量化函数。当这不可能时,您可以使用Numpy或使用Numba或Cython编写自己的函数。

最新更新