Spark GraphX实例(2)

5. 图的转换操作

图的转换操作主要有以下的方法:

(1) Graph.mapVertices():对图的顶点进行转换,返回一张新图;

(2) Graph.mapEdges():对图的边进行转换,返回一张新图。

代码:

    // 转换操作
    println("*************************************************************")
    println("转换操作")
    println("*************************************************************")
    println("顶点的转换操作,顶点age+10:")
    graph.mapVertices{case(id,(name,age)) => (id,(name,age+10))}.vertices.collect.foreach(v => println(s"${v._2._1} is${v._2._2}"))

    println("边的转换操作,边的属性*2:")
    graph.mapEdges(e => e.attr*2).edges.collect.foreach(e => println(s"${e.srcId} to ${e.dstId} att ${e.attr}"))

运行结果:

*************************************************************
转换操作
*************************************************************
顶点的转换操作,顶点age+1:
4 is(Peter,33)
6 is(Kate,24)
2 is(Henry,28)
1 is(Alice,39)
3 is(Charlie,56)
5 is(Mike,36)
边的转换操作,边的属性*3:
2 to 1 att 15
2 to 4 att 6
3 to 2 att 21
3 to 6 att 9
4 to 1 att 3
5 to 2 att 9
5 to 3 att 24
5 to 6 att 24

6. 图的结构操作

图的结构操作主要有:

(1) Graph.subgraph():求图的子图,从图中选出一些顶点,这些顶点以及相应的边就构成了一张子图。

代码:

    println("*************************************************************")
    println("结构操作")
    println("*************************************************************")
    println("顶点年纪>25的子图:")
    val subGraph = graph.subgraph(vpred = (id,vd) => vd._2 >= 25)
    println("子图所有顶点:")
    subGraph.vertices.collect.foreach(v => println(s"${v._2._1} is ${v._2._2}"))
    println
    println("子图所有边:")
    subGraph.edges.collect.foreach(e => println(s"${e.srcId} to ${e.dstId} att ${e.attr}"))

从图中选出年龄大于等于25岁的顶点。运行结果:

*************************************************************
结构操作
*************************************************************
顶点年纪>25的子图:
子图所有顶点:
Peter is 32
Henry is 27
Alice is 38
Charlie is 55
Mike is 35

子图所有边:
2 to 1 att 5
2 to 4 att 2
3 to 2 att 7
4 to 1 att 1
5 to 2 att 3
5 to 3 att 8

7. 图的连接操作

图的连接操作主要有以下方法:

(1) Graph.joinVertices(Graph):对于两个图中都存在的顶点进行转换;

(2) Graph.outerJoinVertices(Graph):和(1)类似,区别在于一个顶点只在前一个图中有,后一个图里面没有,就将这个顶点的属性设为Null。

代码:

    // 连接操作
    println("*************************************************************")
    println("连接操作")
    println("*************************************************************")
    case class User(name:String, age:Int, inDeg:Int, outDeg:Int)

    // 创建一个新图,顶点VD的数据类型为User,并从graph做类型转换
    val initialUserGraph:Graph[User, Int] = graph.mapVertices{case(id,(name,age)) => User(name,age,0,0)}

    // initialUserGraph与inDegrees,outDegrees(RDD)进行连接,并修改initialUserGraph中inDeg值,outDeg值
    val userGraph = initialUserGraph.outerJoinVertices(initialUserGraph.inDegrees){
      case(id, u, inDegOpt) => User(u.name, u.age, inDegOpt.getOrElse(0), u.outDeg)}.outerJoinVertices(initialUserGraph.outDegrees){
      case(id, u, outDegOpt) => User(u.name, u.age, u.inDeg, outDegOpt.getOrElse(0))
    }
    println("连接图的属性:")
    userGraph.vertices.collect.foreach(v => println(s"${v._2.name} inDeg:${v._2.inDeg} outDeg:${v._2.outDeg}"))

    println("出度和入度相同的人员:")
    userGraph.vertices.filter{
      case(id, v) => v.inDeg==v.outDeg
    }.collect.foreach{
      case(id, property) => println(property.name)
    }
    println

其实是一个图分别和自己的入度图、出度图进行连接操作,以便把顶点的出度和入度写入顶点的属性。

运行结果:

*************************************************************
连接操作
*************************************************************
连接图的属性:
Peter inDeg:1 outDeg:1
Kate inDeg:2 outDeg:0
Henry inDeg:2 outDeg:2
Alice inDeg:2 outDeg:0
Charlie inDeg:1 outDeg:2
Mike inDeg:0 outDeg:3
出度和入度相同的人员:
Peter
Henry
原文地址:https://www.cnblogs.com/mstk/p/6914545.html