【发布时间】:2021-05-24 16:33:34
【问题描述】:
我正在尝试通过将具有相同类型(从 1 到 10 的整数)的相邻单元(及其邻居)分配给集群 ID 来将它们聚集到新集群中。
如下图所示,一些集群:
目前,我使用广度优先搜索的缩写来遍历所有邻居及其邻居,然后将 cluster-id 分配给所有找到的相同类型的邻居。由于我的数据集相当大(
我在循环中运行的函数偶然选择单元格,直到所有单元格都被分配了一个集群 ID:
def bfs(df, grid_id):
visited = []
queue = []
visited.append(grid_id)
queue.append(grid_id)
base_pred = df.loc[grid_id, "class"]
while queue:
_ = queue.pop(0)
n, e = get_n_e_index(grid_id)
neighbours = get_same_neighbours(base_pred, n, e, agglo_df)
for neighbour in neighbours:
if neighbour not in visited:
visited.append(neighbour)
queue.append(neighbour)
queue = queue + get_same_neighbours(base_pred, n, e, agglo_df)
return visited
visited用于分配相同的cluster_id
get_same_neighbours 只返回给定单元格的具有相同类型的邻居
在我最终验证该方法之前,我得出的结论是它最终会变慢,并且想知道是否有人知道足够快的算法来解决这个问题。在线搜索解决方案没有帮助。
编辑:花了这么长时间不是算法的问题,但我忘记将可能的起始单元格减少到只有那些以前没有被触及过的单元格。
编辑2:
get_n_e_index 只是将字符串 ID 转换为东北整数
def get_same_neighbours(base_class, north, east, df):
neighbours = []
grid_ids = df["ids"].values
for i in [-1, 1, 0]:
for j in [-1, 1, 0]:
n = int(north + i)
e = int(east + j)
grid_id = get_grid_id(n, e)
invalid = [(-1, 1), (1, 1), (0, 0), (1, -1), (-1, -1)] # invalid combinations
if grid_id in grid_ids and (j, i) not in invalid and base_class == df.loc[grid_id, "class"]:
neighbours.append(grid_id)
return neighbours
get_grid_id 将北 (n) 和东 (e) 整数转换为网格单元的字符串 id。
【问题讨论】:
-
300 万个网格单元看起来并不是一个很大的数字。图像有几百万像素,这种操作即使是基本的图像编辑软件也可以在几秒钟内完成。即使网格人口稀少,通过迭代网格维度和检查单元邻居的详尽搜索也应该足够快。
-
无论如何,您的内部循环中有一个隐藏的线性搜索:
if neighbour not in visited。您需要使用集合而不是列表。 -
你的内部循环的最后一行对我来说没有意义,你正在将当前单元格的邻居一个一个地添加到队列中,并为每个单元格添加整个邻居集邻居。
-
抱歉,我的 while 循环中有一个错误,导致它遍历每个单元格,即使有些单元格可能已经被分配了一个集群。现在所有人都需要4个小时。似乎还是有什么不对劲。最后一行将当前查看的添加邻居的邻居添加到队列中。如果不是,我不明白我实际上做了什么..
标签: python algorithm cluster-analysis