Spark GraphFrames:如何利用连通组件ID查看全部连通节点
看起来你已经成功用GraphFrame算出了连通组件,接下来要把这些结果转化成你想要的连通节点分组或者两两配对的形式其实很简单,我给你两种常用的处理方式:
1. 按组件ID分组查看所有连通节点
你得到的result2数据集里已经包含了每个节点对应的组件ID,只需要用groupBy配合collect_list就能把同一组件下的所有节点聚合到一起,代码如下:
import org.apache.spark.sql.functions.collect_list // 按组件ID分组,收集同一组件的所有节点 val groupedComponents = result2.groupBy("component") .agg(collect_list("id").alias("connected_nodes")) groupedComponents.show(false)
运行后你会得到类似这样的结果:
+---------+-------------------+ |component|connected_nodes | +---------+-------------------+ |1 |[1,4,100,400] | |2 |[2,200] | |3 |[3,300] | +---------+-------------------+
这样就能一眼看到每个组件ID对应的所有连通节点了,完全对应你期望的连通关系。
2. 生成两两连通的节点对(和你期望的输出格式一致)
如果想要得到你列出的那种两两配对的形式,可以通过自连接(self join)实现:把result2和自己按组件ID关联,同时过滤掉重复的配对(比如避免(4,100)和(100,4)同时出现),代码如下:
import org.apache.spark.sql.functions.col val pairwiseConnections = result2.as("a") // 按组件ID关联,并且保证node1的ID小于node2,避免重复配对 .join(result2.as("b"), col("a.component") === col("b.component") && col("a.id") < col("b.id")) .select(col("a.id").alias("node1"), col("b.id").alias("node2")) .orderBy("node1", "node2") pairwiseConnections.show()
运行后就会得到你想要的输出:
+-----+-----+ |node1|node2| +-----+-----+ | 1| 100| | 1| 400| | 4| 100| | 4| 400| | 2| 200| | 3| 300| +-----+-----+
补充说明
GraphFrame的connectedComponents默认会把每个连通组件中的最小节点ID作为该组件的标识(也就是你看到的component列的值),所以你可以通过component ID直接知道这个组件里最小的节点是什么,也能通过上面的分组结果确认每个ID对应的所有节点。
内容的提问来源于stack exchange,提问作者user4046073
相关产品推荐
相关产品推荐

