Spark Graphx常用函式

菜鳥也學大資料發表於2020-11-26

Spark Graph定義

object SparkGraph {
  def main(args: Array[String]): Unit = {
    val spark: SparkSession = SparkSession.builder().master("local").appName("Graph").getOrCreate()
    val sc: SparkContext = spark.sparkContext
    //建立Vertices
    //注意元組的頂點的資料型別只能為Long,否則無法創圖
    val rddVertice: RDD[(Long, String)] = sc.makeRDD(Seq((1L,"A"),(2L,"B"),(3L,"C")))
    //建立Edge
    val rddEdge: RDD[Edge[String]] = sc.makeRDD(Seq(Edge(1L,2L,"aaa"),Edge(2L,3L,"bbb")))
    //建立圖Graph
    val graph1 = Graph(rddVertice,rddEdge)
    }
    //輸出graph
    ((1,A),(2,B),aaa)
	((2,B),(3,C),bbb)

常用函式

	//顯示圖的頂點集合檢視
    println("__________verices_______________")
    graph1.vertices.foreach(println)
    /*
    (1,A)
	(3,C)
	(2,B)
    */
    //顯示圖的邊集合檢視
    println("__________edge_______________")
    graph1.edges.foreach(println)
    /*
    Edge(1,2,aaa)
	Edge(2,3,bbb)
    */
    //顯示圖集合檢視
    println("__________triplets_______________")
    graph1.triplets.foreach(println)
    /*
    ((1,A),(2,B),aaa)
	((2,B),(3,C),bbb)
    */
    //針對Edge過濾資料
    println("__________filter_______________")
    graph1.edges.filter(x=>x.attr.equals("aaa")).foreach(println)
    /*
    Edge(1,2,aaa)
    */
    //圖中邊的數量
    println("____________numEdge__________________")
    println(graph1.numEdges)
    /*
    2
    */
    //圖中頂點數量
    println("______________vertices______________")
    println(graph1.numVertices)
    /*
    3
    */
    //頂點入度數
    println("______________inDegrees__________________")
    graph1.inDegrees.foreach(println)
    /*
    (3,1)
	(2,1)
    */
    //頂點出度數
    println("_______________outDegrees_________________")
    graph1.outDegrees.foreach(println)
    /*
    (1,1)
	(2,1)
    */
    //頂點出入度之和
    println("______________degrees_____________")
    graph1.degrees.foreach(println)
    /*
    (1,1)
	(3,1)
	(2,2)
    */
    
    //mapVertices的使用有點特別,這個方法雖然傳入的是整個頂點資料,但經過操作後的資料結果都只會做為新的value,而不會改變原本key的值
    //def mapVertices[VD2](map: (VertexId, VD) => VD2): Graph[VD2, ED]
    println("_________________mapVertices_______________________")
    //只改變value,使所有頂點value加上”x“
    graph1.mapVertices((x,y)=>(y+"x")).vertices.foreach(println)
    /*
    (1,Ax)
    (3,Cx)
    (2,Bx)
     */
    //將key值加1,value加上”x“
    //這裡雖然改變了key值,但最後也會把整體作為新的元組存放在value的位置
    graph1.mapVertices((x,y)=>(x+1,y+"x")).vertices.foreach(println)
    /*
    (1,(2,Ax))
    (3,(4,Cx))
    (2,(3,Bx))
     */

    //mapEdge
    //def mapEdges[ED2](map: Edge[ED] => ED2): Graph[VD, ED2]
    //傳入的是Edge,經過處理後的的資料結果,返回到的位置是兩個頂點的之間的屬性
    println("_______________mapEdge_________________________")
    graph1.mapEdges(x=>x.srcId+"/"+x.dstId+"/"+x.attr).edges.foreach(println)
	/*
    Edge(1,2,1/2/aaa)
	Edge(2,3,2/3/bbb)
    */

    //反轉
    println("________________reverse_______________________")
    graph1.reverse.triplets.foreach(println)
	/*
    ((2,B),(1,A),aaa)
	((3,C),(2,B),bbb)
    */
    
    //subgraph擷取
    //x傳入的是每行圖資料
    println("_______________subgraph____________________")
    graph1.subgraph(x=>x.attr.equals("aaa")).triplets.foreach(println)
	/*
    ((1,A),(2,B),aaa)
    */
    
    //joinVertice
    //將圖裡的頂點與另一個RDD頂點進行join,最後將處理過後的值作為頂點新的屬性
    println("_______________joinVertice____________________")
    val rddVertice2: RDD[(VertexId, PartitionID)] = sc.makeRDD(Array((1L,1),(2L,2),(3L,3),(4L,4)))
    graph1.joinVertices(rddVertice2)((id,v1,v2)=>(v1+v2)).vertices.foreach(println)
	/*
    (1,A1)
	(3,C3)
	(2,B2)
    */
    
    //outerJoinVertice
    println("________________outerJoinVertice___________________________")
    //定義樣例類User,屬性有ID,入度數,出度數
    case class User(x:String,inDeg:Int,outDeg:Int)
    //實現將ID與入度數儲存在User中,出度數設為0
    graph1.outerJoinVertices(graph1.inDegrees){ case(key,value,inDeg)=>User(value,inDeg.getOrElse(0),0)}
    //在outerJoin頂點出度數
      .outerJoinVertices(graph1.outDegrees){case(key,value,outDeg)=>User(value.x,value.inDeg,outDeg.getOrElse(0))}.vertices.foreach(println)
     /*
    (1,User(A,0,1))
	(3,User(C,1,0))
	(2,User(B,1,1))
    */
  }

相關文章