【问题标题】:How to create Directional graph with Spark Graphx or Graphframe如何使用 Spark Graphx 或 Graphframe 创建方向图
【发布时间】:2017-02-27 18:00:41
【问题描述】:

我正在尝试在我的数据集上但在有向图上运行连通分量算法。我不希望连接的组件在边缘的两个方向上都是横向的。

这是我的示例代码

import org.apache.log4j.{Level, LogManager}
import org.apache.spark.SparkConf
import org.apache.spark.graphx.Edge
import org.apache.spark.sql._
import org.graphframes._

object CCTest {

def main(args: Array[String]) {

  val sparkConf = new SparkConf()
      .setMaster("local[2]")
    .setAppName("cc_test")


  implicit val sparkSession = SparkSession.builder().config(sparkConf).getOrCreate()

  val sc = sparkSession.sparkContext

  val vertex = sparkSession.createDataFrame(sc.parallelize(Array(
    (1L, "b4fcde907cbd290b7e16", 28),
    (2L, "cda389612d6b37674cb1", 27),
    (3L, "1a6a6e3fd2daaeeb2a05", 65),
    (4L, "9a007eee210a47e58047", 42),
    (5L, "e91898d39bf5f8501827", 55),
    (6L, "ceab58c59d23549d3f4b", 50),
    (12L, "ceab58c59asd3549d3f4b", 50),
    (14L, "ceab508c59d23549d3f4b", 55),
    (15L, "ceab508c59d23541d3f4b", 51)
  ))).toDF("id", "similar_hash", "size")

  val edges = sparkSession.createDataFrame(sc.parallelize(Array(
            Edge(2L, 1L, 0.7f),
            Edge(2L, 4L, 0.2f),
            Edge(3L, 2L, 0.4f),
            Edge(3L, 6L, 0.3f),
            Edge(4L, 1L, 0.1f),
            Edge(5L, 2L, 0.2f),
            Edge(5L, 3L, 0.8f),
            Edge(5L, 6L, 0.3f),
            Edge(12L, 14L, 1.3f),
            Edge(15L, 14L, 1.3f)    //< - should not be connected except (14L, 15L)
          ))).toDF("src", "dst", "attr")


  val graph = GraphFrame(vertex, edges)

  val cc = graph.connectedComponents.run()

  cc.show()



  sparkSession.stop()

}

 }

结果:

+---+--------------------+----+---------+
| id|        similar_hash|size|component|
+---+--------------------+----+---------+
|  6|ceab58c59d23549d3f4b|  50|        1|
|  5|e91898d39bf5f8501827|  55|        1|
|  1|b4fcde907cbd290b7e16|  28|        1|
|  3|1a6a6e3fd2daaeeb2a05|  65|        1|
| 12|ceab58c59asd3549d...|  50|       12|
|  2|cda389612d6b37674cb1|  27|        1|
|  4|9a007eee210a47e58047|  42|        1|
| 14|ceab508c59d23549d...|  55|       12|
| 15|ceab508c59d23541d...|  51|       12|   <- should be in separate cluster
+---+--------------------+----+---------+

请问我怎样才能做到这一点?

【问题讨论】:

  • @zero323 我不认为 SCC 可以在这里使用(如果我错了,请纠正我),因为它要求每个节点都可以从其他节点访问。但基本上,我需要像 SQL 递归查询一样进行递归。例如:a -> b, b -> c, m -> b Strongly CC:Set = {a, b}, Set = {b, c}, Set = {m, b} 连通分量:它将是set = {a, b, d, m} -- 注意和m 也连接到节点a -&gt; b -&gt; m 但是在递归中 a -> b -> c = {a, b, c} and m -> b = {m, b} this给出两个集合 {a, b, c} 和 {m, b}
  • 好的。那么为什么是{a, b, c}{m, b} 而不是{a, b, c}{m, b, c}?无论哪种方式,您似乎都需要 Pregel API。
  • @zero323 正确 - {a, b, c} 和 {m, b, c}。我想到了 Pregel API。我也试试看 - 谢谢
  • 如果我可以建议我会尝试澄清问题。看起来您在寻找 DFS 或可达性图而不是连接组件。

标签: scala apache-spark spark-graphx graphframes


【解决方案1】:

我可能弄错了,但我的解决方案直接源于connectedComponentssource code。在第 54 行,系统本身只调用了一个 Pregel 迭代器,关键行是

val pregelGraph = Pregel(ccGraph, initialMsg, maxIterations, EdgeDirection.Either)

只需将EdgeDirection 更改为更合适的参数(可以找到here),这可能对您有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    • 1970-01-01
    • 1970-01-01
    • 2018-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多