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

被折叠的 条评论
为什么被折叠?



