Spark高级数据分析——纽约出租车轨迹的空间和时间数据分析

原文地址:https://www.jianshu.com/p/eb6f3e0c09b5

作者:IIGEOywq

一、地理空间分析:

object RunGeoTime extends Serializable {

  val formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH)

  def main(args: Array[String]): Unit = {

    /*--------------1.初始化SparkContext-------------------*/
val sc = new SparkContext(new SparkConf().setAppName("SpaceGeo")) /*--------------2.读取HDFS数据-------------------*/
val taxiRaw = sc.textFile("hdfs://master:9000/taxidata") /*--------------3.出租车数据预处理------------------*/
//3.1 利用自定义的safe函数处理原始数据
val safeParse = safe(parse)
val taxiParsed = taxiRaw.map(safeParse)
//taxiParsed数据持久化
taxiParsed.cache() //查看非法数据
/* val taxiBad = taxiParsed.collect({
case t if t.isRight => t.right.get
})*/ //collect返回到驱动器,为了单机开发和测试使用,不建议集群使用
//taxiBad.collect().foreach(println) /*val taxiGood = taxiParsed.collect({
case t if t.isLeft => t.left.get
})
taxiGood.cache()*/ //3.2 剔除非法数据结果,获得正确格式的数据
val taxiGood=taxiParsed.filter(_.isLeft).map(_.left.get)
taxiGood.cache() //自定义一次打车的乘坐时间函数
def hours(trip: Trip): Long = {
val d = new Duration(trip.pickupTime, trip.dropoffTime)
d.getStandardHours
}
//3.3 打印统计乘客上下车时间的记录,打印结果如执行分析结果图中的1
taxiGood.values.map(hours).countByValue().toList.sorted.foreach(println)
taxiParsed.unpersist() //根据上面的输出结果,统计一次乘车时间大于0小于3小时的记录
val taxiClean = taxiGood.filter {
case (lic, trip) => {
val hrs = hours(trip)
0 <= hrs && hrs < 3
}
} /*--------------4.出租车数据空间分析------------------*/
//4.1 获取纽约行政区划数据
val geojson = scala.io.Source.fromURL(getClass.getResource("/nyc-boroughs.geojson")).mkString
//转换为地理要素
val features = geojson.parseJson.convertTo[FeatureCollection] val areaSortedFeatures = features.sortBy(f => {
val borough = f("boroughCode").convertTo[Int]
(borough, -f.geometry.area2D())
}) val bFeatures = sc.broadcast(areaSortedFeatures)
//4.2 判断乘客下车点落在那个行政区
def borough(trip: Trip): Option[String] = {
val feature: Option[Feature] = bFeatures.value.find(f => {
f.geometry.contains(trip.dropoffLoc)
})
feature.map(f => {
f("borough").convertTo[String]
})
}
//4.3 第一次统计打印各行政区下车点的记录,打印结果如执行分析结果图中的2
taxiClean.values.map(borough).countByValue().foreach(println) //4.4 剔除起点和终点数据缺失的数据
def hasZero(trip: Trip): Boolean = {
val zero = new Point(0.0, 0.0)
(zero.equals(trip.pickupLoc) || zero.equals(trip.dropoffLoc))
} val taxiDone = taxiClean.filter {
case (lic, trip) => !hasZero(trip)
}.cache() //4.5 踢出零点数据后统计打印各行政区下车点的记录,打印结果如执行分析结果图中的3
taxiDone.values.map(borough).countByValue().foreach(println)
taxiGood.unpersist() //输出地理空间分析结果到HDFS
//taxiDone.saveAsTextFile("hdfs://master:9000/GeoResult") } //字符串转double
def point(longitude: String, latitude: String): Point = {
new Point(longitude.toDouble, latitude.toDouble)
} //获取taxiraw RDD记录中的出租车司机驾照和Trip对象
def parse(line: String): (String, Trip) = {
val fields = line.split(',')
val license = fields(1)
// Not thread-safe:
val formatterCopy = formatter.clone().asInstanceOf[SimpleDateFormat]
val pickupTime = new DateTime(formatterCopy.parse(fields(5)))
val dropoffTime = new DateTime(formatterCopy.parse(fields(6)))
val pickupLoc = point(fields(10), fields(11))
val dropoffLoc = point(fields(12), fields(13)) val trip = Trip(pickupTime, dropoffTime, pickupLoc, dropoffLoc)
(license, trip)
} //非法记录数据处理函数
def safe[S, T](f: S => T): S => Either[T, (S, Exception)] = {
new Function[S, Either[T, (S, Exception)]] with Serializable {
def apply(s: S): Either[T, (S, Exception)] = {
try {
Left(f(s))
} catch {
case e: Exception => Right((s, e))
}
}
}
} }

二、pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.cloudera.datascience.geotime</groupId>
<artifactId>ch08-geotime</artifactId>
<packaging>jar</packaging>
<name>Temporal and Geospatial Analysis</name>
<version>2.0.0</version> <dependencies>
<!--注意 scala版本对应spark集群中scala的版本,provided属性要加上 -->
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>2.11.8</version>
<scope>provided</scope>
</dependency>
<!--注意 hadoop版本对应spark集群中hadoop的版本,provided属性要加上 -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.3</version>
<scope>provided</scope>
</dependency>
<!--注意 spark版本对应spark集群中spark的版本,2.11是对应的scala版本 -->
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>2.0.1</version>
<scope>provided</scope>
</dependency>
<!--nscala-time时间处理库,2.11是对应的scala版本 -->
<dependency>
<groupId>com.github.nscala-time</groupId>
<artifactId>nscala-time_2.11</artifactId>
<version>1.8.0</version>
</dependency>
<!--esri空间关系库,2.11是对应的scala版本 -->
<dependency>
<groupId>com.esri.geometry</groupId>
<artifactId>esri-geometry-api</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>io.spray</groupId>
<artifactId>spray-json_2.11</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.4</version>
</dependency>
</dependencies> <build>
<plugins>
<!--scala-maven插件必须加上,否则打包后无主程序 -->
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<scalaVersion>2.11.8</scalaVersion>
<scalaCompatVersion>2.11.8</scalaCompatVersion>
<args>
<arg>-unchecked</arg>
<arg>-deprecation</arg>
<arg>-feature</arg>
</args>
<javacArgs>
<javacArg>-source</javacArg>
<javacArg>1.8.0</javacArg>
<javacArg>-target</javacArg>
<javacArg>1.8.0</javacArg>
</javacArgs>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<!--maven-assembly插件可以打包应用的依赖包 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<mainClass>com.cloudera.datascience.geotime.RunGeoTime</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<recompressZippedFiles>false</recompressZippedFiles>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- 用于maven继承项目的聚合 -->
<phase>package</phase> <!-- 绑定到package阶段 -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build> </project>

Spark高级数据分析——纽约出租车轨迹的空间和时间数据分析的更多相关文章

  1. SQL server 创建 修改表格 及表格基本增删改查 及 高级查询 及 (数学、字符串、日期时间)函数[转]

    SQL server 创建 修改表格 及表格基本增删改查 及 高级查询 及 (数学.字符串.日期时间)函数   --创建表格 create table aa ( UserName varchar(50 ...

  2. 表空间基于时间点的恢复(TSPITR)

    环境:RHEL 6.4 + Oracle 11.2.0.4 准备模拟环境 1. 验证表空间的依赖性 2. 确定执行TSPITR后会丢失的对象 3. 自动执行TSPITR Reference 准备模拟环 ...

  3. Redis学习笔记~关于空间换时间的查询案例

    回到目录 空间与时间 空间换时间是在数据库中经常出现的术语,简单说就是把查询需要的条件进行索引的存储,然后查询时为O(1)的时间复杂度来快速获取数据,从而达到了使用空间存储来换快速的时间响应!对于re ...

  4. Redis基础知识之————空间换时间的查询案例

    空间与时间 空间换时间是在数据库中经常出现的术语,简单说就是把查询需要的条件进行索引的存储,然后查询时为O(1)的时间复杂度来快速获取数据,从而达到了使用空间存储来换快速的时间响应!对于redis这个 ...

  5. 你好,C++(28)用空间换时间 5.2 内联函数 5.3 重载函数

    5.2  内联函数 通过5.1节的学习我们知道,系统为了实现函数调用会做很多额外的幕后工作:保存现场.对参数进行赋值.恢复现场等等.如果函数在程序内被多次调用,且其本身比较短小,可以很快执行完毕,那么 ...

  6. 计数排序(O(n+k)的排序算法,空间换时间)

    计数排序就是利用空间换时间,时间复杂度O(n+k) n是元素个数,k是最大数的个数: 统计每个数比他小的有多少,比如比a[i]小的有x个,那么a[i]应该排在x+1的位置 代码: /* * @Auth ...

  7. JDK1.8 LongAdder 空间换时间: 比AtomicLong还高效的无锁实现

    我们知道,AtomicLong的实现方式是内部有个value 变量,当多线程并发自增,自减时,均通过CAS 指令从机器指令级别操作保证并发的原子性. // setup to use Unsafe.co ...

  8. flask 第四章 偏函数 Local空间转时间 myLocalStack RunFlask+request 请求上下文

    1 . 偏函数 (partial) from functools import partial def func(*args,**kwargs): a=args b=kwargs return a,b ...

  9. Oracle之表空间基于时间点的恢复

    记一次优化过程中:一次误操作,在不影响其他表空间的情况下:采用表空间基于时间点的恢复(TSPITR)方法恢复数据的过程. 1.TSPITR恢复原理    TSPITR目前最方便的方法是使用RMAN进行 ...

随机推荐

  1. 发起一个开源项目:基于 .NET 的博客引擎 fluss

    今天我们发起一个开源项目,它的名字叫 fluss,fluss 是 river 的德语. 百川归海,每一个博客就如一条河流,输入的是文字,流出的是知识,汇入的是知识的汪洋大海. 川流不息,fluss 是 ...

  2. body-parser 源码分析

    body-parser 源码分析 预备知识:熟悉 express 的中间件逻辑 阅读事件:30min 1. body-parser 解决什么问题 在 node http 模块中,您只能通过 data ...

  3. 对HTTP请求接口资源下载时间过长的问题分析

    问题描述 我司某产品线有指定业务接口customQuery在线上环境中,与首页一起打开时下载数据的时间明显过长(平均可以达到2s) 注: "与首页一起打开" 的含义是指用户进入WE ...

  4. python 虾米停服了...用python爬取虾米最近播放的1000首歌

    1. 虾米关服 在这里插入图片描述 用了5年多的音乐软件就这么说关就关了,确实让人心里不好受 ,虽然再去一个新的app里,让它们的算法熟悉你的喜好也不是很困难,可我还是习惯虾米的界面.虾米现在可以支持 ...

  5. NOIP初赛篇——10计算机网络

    网络的定义 ​ 所谓计算机网络,就是利用通信线路和设备,把分布在不同地理位置上的多台计算机连接起来. ​ 计算机网络是现代通信技术与计算机奇数结合的产物. ​ 网络中计算机与计算机之间的通信依靠协议进 ...

  6. 【ORACLE】11g rac+dg

    首先感谢群友分享的文档,在这里先感谢哆啦B梦,非常感谢 该文档主要指导如何利用现有的RAC环境搭建一套RAC与单实例的DG的环境  ============================主机配置信息 ...

  7. kubernets之服务重定向

    一  服务的强大功能之处的其他表现 前面介绍的所有有关服务的说明,都是将集群内部的pod应用暴露出来提供外部客户端或者内部的客户端进行访问,但是服务的强大之处远远不止于此 服务甚至可以将集群外部的应用 ...

  8. Netty中使用的设计模式

    创建型 简单工厂 public class DefaultThreadFactory implements ThreadFactory { @Override public Thread newThr ...

  9. MYSQL基础知识的复习2

    1.修改表中的数据 update 表名 set 要修改的字段 where 条件;-- 如果修改多个字段那么字段和字段之间用逗号隔开 2.查询(很重要) 1.查询表中部分字段: select 字段名,字 ...

  10. linux编译模块,包含了头文件却还是报undifind警告

    在编写一个自己写的gadget驱动的时候遇到一个这样的问题,编译的时候报了个警告:WARNING: "usb_composite_register" [-/my_zero.ko] ...