Graphx ~7:航空公司数据提取与简单计算

本文介绍如何使用GraphX处理航空公司数据,统计机场与航线数量,计算最长航线,寻找最繁忙及重要机场,以及最便宜航线的方法。

写在前面

此练习的源文件在此处免费下载

本文为了方便,未在代码中做删除第一行的工作,请下载后用Excel手动删除第一行的字段
在这里插入图片描述

数据格式

dom – 月中第几天 (day of month)
dow – 周中第几天 (day of week)
carrier – 航空公司
tail_num – 飞机注册号
fl_num – 航班号
origin_id – 起飞机场编号
origin – 起飞机场
dest_id – 到达机场编号
dest – 到达机场
crs_dep_time – 预计起飞时间
dep_time – 起飞时间
dep_delay_mins – 起飞延迟 (分钟)
crs_arr_time – 预计到达时间
arr_time – 到达时间
arr_delay_mins – 到达延迟 (分钟)
crs_elapse_time – 预计飞行时间
dist – 飞行距离

项目要求

统计航班飞行网图中机场的数量
统计航班飞行网图中航线的数量
计算最长的飞行航线(Point to Point)
找出最繁忙的机场
找出最重要的飞行航线(PageRank)
找出最便宜的飞行航线

代码实现

创建SparkContext

val conf = new SparkConf().setAppName("airportdemo").setMaster("local[2]")
val sc = SparkContext.getOrCreate(conf)

加载数据
注:此处使用textFile函数从计算机本地获取到源文件,然后通过 Spark map 算子函数进行格式化,返回一个新的分布式数据集,用 " , " 将打断后的数据赋给对象 flights

val flights=sc.textFile(
	"file:///E:\\it-自总结\\bigdata\\大数据的笔记\\Spark\\USA Flight Datset - Spark Tutorial - Edureka1.csv")
     .map(x=>x.split(","))

创建 点集合,边集合,构建图

# 创建点集合
	 val airPorts = flights.flatMap(x=>Array((x(5).toLong,x(6)),(x(7).toLong,x(8)))).distinct()
# 创建边集合
	val lines = flights.map(x=>(x(5).toLong,x(7).toLong,x(16).toInt))
      .distinct().map(x=>Edge(x._1,x._2,x._3))
# 构建图
	val graph = Graph(airPorts,lines)

查看机场个数

println("机场数量 : " + graph.numVertices)

查看航线数量

println("航线数量 : " + graph.numEdges)

计算最长的飞行航线

graph.triplets.sortBy(_.attr, false).take(1)
  .map(x => "航线距离最长 : " + x.srcAttr + "---->" + x.dstAttr + "----距离 : " + x.attr)
  .foreach(println)

找到最繁忙的机场

- 即找到 入度 和 出度 数量最多的 点

– 入度

graph.inDegrees
	.sortBy(_._2, false)
  	.take(1)
 	.foreach(x => println("入度最多机场 : " + x))

– 出度

graph.outDegrees
	.sortBy(_._2, false)
	.take(1)
	.foreach(x => println("出度最多机场 : " + x))

找到最重要的机场

graph.pageRank(0.05).vertices.join(airports)
         .sortBy(_._2._1, false)
         .take(3)
         .map(x => (x._2._2, x._2._1))
         .foreach(println)

找到最便宜的飞行航线

计算公式 : price = 180.0 + distance * 0.15

//取得一个点作为原点,可随机设置,也可以手动设置
//此处使用手动设置,机场编号12478
val source_id: VertexId = 12478
//初始化一个图,包括点和边
private val init_graph: Graph[Double, Double] = 
	graph.mapVertices((id, _) => 
	if (id == source_id) 0.0 else Double.PositiveInfinity)
	.mapEdges(e => e.attr.toDouble * 0.15)

//这里需要使用到pregel方法,需要事先定义 接受消息 发送消息 合并消息 三个值
//接受消息
val f1: (VertexId, Double, Double) => Double = 
	(id, dist, new_dist) => math.min(dist, new_dist)

//(筛选)发送消息
val f2: EdgeTriplet[Double, Double] => Iterator[(VertexId, Double)] = triplet =>
{
        if (triplet.srcAttr + triplet.attr < triplet.dstAttr) 
        	Iterator((triplet.dstId,triplet.srcAttr + triplet.attr))
        else 
        	Iterator.empty
}

//合并
val f3: (Double, Double) => Double = (x, y) => math.min(x, y)

//调用pregel函数进行计算
val pregel_graph: Graph[Double, Double] = 
	init_graph.pregel(Double.PositiveInfinity)(f1, f2, f3)


//输出
pregel_graph.vertices.filter(x => x._2 != 0).takeOrdered(1)
{
	Ordering.by(x => x._2)
}.foreach(x => println(s"从$source_id 出发到 ${x._1}最便宜的价格为: ${x._2}"))

或者

println("----------------计算最便宜的航线-----------------")
    val count:VertexId=airPorts.count()
    val f=1.0
    val sample: RDD[(VertexId, String)] = airPorts.sample(false,f/count,count)

    val source_id:VertexId=sample.first()._1
    val initialGraph: Graph[Double, Double] = graph.mapVertices((id, name) =>
      if (id == source_id) 0.0 else Double.PositiveInfinity)
      .mapEdges(e => (e.attr.toDouble * 0.15)+180)

    val pregel_graph: Graph[Double, Double] = initialGraph.pregel(
      Double.PositiveInfinity,
      Int.MaxValue,
      EdgeDirection.Out
    )(
      (id: VertexId, dist: Double, new_dist: Double) => math.min(dist, new_dist),
      (triplet) => {
        if (triplet.srcAttr + triplet.attr < triplet.dstAttr) {
          Iterator((triplet.dstId, triplet.srcAttr + triplet.attr))
        } else {
          Iterator.empty
        }
      },
      (a, b) => math.min(a, b)
    )
    val cheap_lines: Array[(VertexId, VertexId, Double)] = pregel_graph.edges.map { case (Edge(srcId, dstId, price)) => (srcId, dstId, price) }
      .takeOrdered(3)(Ordering.by(_._3))
    println("最便宜的航线:")
    cheap_lines.foreach(println)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值