【发布时间】:2014-01-29 04:27:02
【问题描述】:
我是 python 新手。我将dbscan 代码用于集群目的并进行了一些更改。现在代码运行良好,但速度很慢。所以我发现我必须从我的代码中删除'for循环'。这是代码的一部分:
class Point:
def __init__(self, x = 0, y = 0, visited = False, isnoise = False):
self.x = x
self.y = y
self.visited = False
self.isnoise = False
def show(self):
return self.x, self.y
def dist(self, p1, p2):
#Calculate the great circle distance between two points on the earth (specified in decimal degrees)return distance between two point
# convert decimal degrees to radians
dlat = radians(p2.x-p1.x)
dlon = radians(p2.y-p1.y)
a = sin(dlat/2) * sin(dlat/2) + cos(radians(p1.x))* cos(radians(p2.x)) * sin(dlon/2) * sin(dlon/2)
c = 2 * atan2(sqrt(a), sqrt(1-a))
d = 6371 * c
return d
def distanceQuery(self,neighbor_pts):
dista=[]
for i in range(len(neighbor_pts)):
for j in range(i+1,len(neighbor_pts)):
z=self.dist(neighbor_pts[i],neighbor_pts[j])
dista.append(z)
return max(dista)
distanceQuery 函数使用双循环。有什么办法可以删除这个吗?我可以向量化这个双循环吗?由于这是集群代码,因此有一些步骤需要附加。我已经读过 numpy 数组在追加时的工作方式与 python 列表不同。附加 numpy 数组效率低下。
编辑:
所以这可以向量化。但这是代码的其他部分,在我检查某些条件之后发生追加。
def expandCluster(self, P, neighbor_points):
self.cluster[self.cluster_inx].append(P)
iterator = iter(neighbor_points)
while True:
try:
npoint_tmp = iterator.next()
except StopIteration:
# StopIteration exception is raised after last element
break
if (not npoint_tmp.visited):
#for each point P' in NeighborPts
npoint_tmp.visited = True
NeighborPts_ = self.regionQuery(npoint_tmp)
if (len(NeighborPts_) >= self.MinPts):
for j in range(len(NeighborPts_)):
neighbor_points.append(NeighborPts_[j])
if self.distanceQuery(neighbor_points)>0.10:
break
现在,如果我也对neighbor_points 进行矢量化。我将不得不解决附加问题?所以每个点都会附加到 neighbour_points 中,然后它会生成一个 distanceQuery 。而这个过程也是一个迭代的一部分。所以这里也有两个循环。我只是想确保在 numpy 数组中追加不会效率低下
【问题讨论】:
-
我认为这可能是一个 XY 问题 - 你能描述一下你的目标是什么,而不仅仅是让你到达那里的部分路线吗?我认为可能有一个解决方案涉及
scipy.spatial.KDTree -
@Eric 我的目标是使用 dbscan 进程获取集群,但同时使用“该集群中任意两点之间的最大距离”限制这些集群。我正在尝试控制集群的大小
标签: python numpy vectorization