目录
2.3 first()/head()/take()/takeAsList():获取若干条记录
2.4 collect()/collectAsList():获取所有数据
一、Scala基础
1、Scala常用数据类型
数据类型 | 描述 |
---|---|
Int | 32位有符号补码整数。数值区间为32768~32767 |
Float | 32位IEEE754(IEEE浮点数算数标准)单精度浮点数 |
Double | 64位IEEE754(IEEE浮点数算数标准)双精度浮点数 |
String | 字符序列,即字符串 |
Boolean | 布尔值,true或false |
Unit | 表示无值,作用同java中void用法 是不返回任何结果的方法的结果类型 |
2、定义使用数组与数组的常用方法
2.1定义与使用数组
数组是Scala中常用的一种数据结构,数组是一种存储了相同类型元素的固定大小的顺序集合,
Scala定义一个数组的语法格式如下:
# 第1种方式
var arr: Array[String] = new Array[String](num)
# 第2种方式
var arr:Array[String] = Array(元素1,元素2,…)
2.2数组的常用方法
方法 | 描述 |
length | 返回数组的长度 |
head | 查看数组的第一个元素 |
tail | 查看数组中除了第一个元素外的其他元素 |
isEmpty | 判断数组是否为空 |
contains(x) | 判断数组是否包含元素x |
3、定义与使用函数
函数是Scala的重要组成部分,Scala作为支持函数式编程的语言,可以将函数作为对象.
定义函数的语法格式如下:
# def functionName(参数列表):[return type]={}
Scala提供了多种不同的函数调用方式,以下是调用函数的标准格式。
# functionName(参数列表)
如果函数定义在一个类中,那么可以通过“类名.方法名(参数列表)”的方式调用
4、列表操作常用方法
方法 | 描述 |
def head: A | 获取列表的第一个元素 |
def init:List[A] | 返回所有元素,除了最后一个元素 |
def last:A | 获取列表的最后一个元素 |
def tail:List[A] | 返回所有元素,除了第一个元素 |
def :::(prefix: List[A]): List[A] | 在列表开头添加指定列表的元素 |
def take(n: Int): List[A] | 获取列表前n个元素 |
def contains(elem: Any): Boolean | 判断列表是否包含指定元素 |
Scala中常用的查看列表元素的方法有head、init、last、tail和take()。
head:查看列表的第一个元素。
tail:查看第一个元素之后的其余元素。
last:查看列表的最后一个元素。
Init:查看除最后一个元素外的所有元素。
take():查看列表前n个元素。
5、集合操作常用方法
方法 | 描述 |
def head: A | 获取集合的第一个元素 |
def init:Set[A] | 返回所有元素,除了最后一个 |
def last:A | 获取集合的最后一个元素 |
def tail:Set[A] | 返回所有元素,除了第一个 |
def ++(elems: A): Set[A] | 合并两个集合 |
def take(n: Int): List[A] | 获取列表前n个元素 |
def contains(elem: Any): Boolean | 判断集合中是否包含指定函数 |
Scala合并两个列表时使用的是:::()或concat()方法,而合并两个集合使用的是++()方法。
5.1 map()方法
可通过一个函数重新计算列表中的所有元素,并且返回一个包含相同数目元素的新列表。
5.2 foreach()方法
和map()方法类似,但是foreach()方法没有返回值,只用于对参数的结果进行输出。
5.3 filter()方法
可以移除传入函数的返回值为false的元素。
5.4 flatten()方法
可以将嵌套的结构展开,即flatten()方法可以将一个二维的列表展开成一个一维的列表。
5.5 flatMap()方法
结合了map()方法和flatten()方法的功能,接收一个可以处理嵌套列表的函数,再对返回结果进行连接。
5.6 groupBy()方法
可对集合中的元素进行分组操作,返回的结果是一个映射。
6、定义与使用映射
1. 映射( Map ) 是一种可迭代的键值对结构 。
2. 所有的值都可以通过键来获取 ,并且映射中的键都是唯一的 。
3. 集合操作常用方法同样也适合映射。
4. 另外映射还可以通过 keys 方法获取所有的键,通过 values 方法获取所有值,也可以通过 isEmpty 方法判断映射的数据是否为空
7、定义与使用元组
1.元组(Tuple)是一种类似于列表的结构,但与列表不同的是,元组可以包含不同类型的元素。
2.元组的值是通过将单个的值包含在圆括号中构成的
3.目前,Scala支持的元组最大长度为22,即Scala元组最多只能包含22个元素
4.访问元组元素可以通过“元组名称._元素索引”进行,索引从1开始
二、Spark编程基础
1、从内存中读取创建RDD
1.1parallelize()方法
有两个输入参数,说明如下。
要转化的集合,必须是Seq集合。Seq表示序列,指的是一类具有一定长度的、可迭代访问的对象,其中每个数据元素均带有一个从0开始的、固定的索引。
分区数。若不设分区数,则RDD的分区数默认为该程序分配到的资源的CPU核心数。
1.2makeRDD()方法
有两种使用方式。
第一种方式的使用与parallelize()方法一致;
第二种方式是通过接收一个是Seq[(T,Seq[String])]参数类型创建RDD。
第二种方式生成的RDD中保存的是T的值,Seq[String]部分的数据会按照Seq[(T,Seq[String])]的顺序存放到各个分区中,一个Seq[String]对应存放至一个分区,并为数据提供位置信息,通过preferredLocations()方法可以根据位置信息查看每一个分区的值。调用makeRDD()时不可以直接指定RDD的分区个数,分区的个数与Seq[String]参数的个数是保持一致的。
2、从外部存储系统中读取数据创建RDD
从外部存储系统中读取数据创建 RDD 的方法可以有很多种数据来源,可通过SparkContext对象的 textFile0方法读取数据集。textFileO方法支持多种类型的数据集,如目录、文本文件、压缩文件和通配符匹配的文件等,并且允许设定分区个数,分别读取 HDFS文件和Linux本地文件的数据并创建 RDD,具体操作如下。
(1)通过HDFS文件创建 RDD
这种方式较为简单和常用,直接通过 textFile()方法读取 HDFS文件的位置即可。
在HDFS 的/user/toot 目录下有一个文件test.txt,读取该文件创建一个 RDD
val test = sc. textile ("/user/root/test.txt")
(2)通过 Linux 本地文件创建 RDD
本地文件的读取也是通过 sc.textFile("路径")的方法实现的,在路径前面加上“file://”表示从Linux 本地文件系统读取。在 IntelliJIDEA 开发环境中可以直接读取本地文件;但在 spark-shell 中,要求在所有节点的相同位置保存该文件才可以读取它,例如,在Linux的/opt 目录下创建一个文件 test.txt,任意输入4行数据并保存,将 test.txt 文件远程传输至所有节点的/opt 目录下,才可以读取文件 test.txt。读取 test.txt 文件,并且统计文件的数据行数,代码如下
3、RDD方法总结
3.1 使用map()方法转换数据
map()方法是一种基础的RDD转换操作,可以对 RDD 中的每一个数据元素通过某种函数进行转换并返回新的RDD。mapO方法是懒操作,不会立即进行计算。
转换操作是创建RDD的第二种方法,通过转换已有RDD生成新的RDD。因为RDD是一个不可变的集合,所以如果对 RDD 数据进行了某种转换,那么会生成一个新的 RDD。
例如,通过一个存放了5个 Int类型的数据元素的列表创建一个 RDD,可通过 map0方法对每一个元素进行平方运算,结果会生成一个新的RDD,代码如下:
3.2 使用 sortBy()方法进行排序
用于对标准RDD进行排序,有3个可输入参数,说明如下。
第1个参数是一个函数f:(T) => K,左边是要被排序对象中的每一个元素,右边返回的值是元素中要进行排序的值。
第2个参数是ascending,决定排序后RDD中的元素是升序的还是降序的,默认是true,即升序排序,如果需要降序排序那么需要将参数的值设置为false。
第3个参数是numPartitions,决定排序后的RDD的分区个数,默认排序后的分区个数和排序之前的分区个数相等,即this.partitions.size。
第一个参数是必须输入的,而后面的两个参数可以不输入。
3.3 使用collect()方法查询数据
collectO方法是一种行动操作,可以将 RDD 中所有元素转换成数组并返回到 Driver 端,适用于返回处理后的少量数据。因为需要从集群各个节点收集数据到本地,经过网络传输,并且加载到 Driver 内存中,所以如果数据量比较大,会给网络传输造成很大的压力。因此,数据量较大时,尽量不使用collectO方法,否则可能导致Driver 端出现内存溢出间题。collectO方法有以下两种操作方式。
(1) collect:直接调用 collect 返回该 RDD 中的所有元素,返回类型是一个 Array[T数组,这是较为常用的一种方式。
(2)collect[U: ClassTag](f: PartialFunction[T, U]):RDD[U]。这种方式需要提供一个标准的偏函数,将元素保存至一个RDD中。首先定义一个函数one,用于将collect方法得到的数组中数值为1的值替换为“one”,将其他值替换为“other”。
3.4 使用flatMap()方法转换数据
flatMap()方法将函数参数应用于RDD之中的每一个元素,将返回的迭代器(如数组、列表等)中的所有元素构成新的RDD。
使用flatMap()方法时先进行map(映射)再进行flat(扁平化)操作,数据会先经过跟map一样的操作,为每一条输入返回一个迭代器(可迭代的数据类型),然后将所得到的不同级别的迭代器中的元素全部当成同级别的元素,返回一个元素级别全部相同的RDD。这个转换操作通常用来切分单词。
例如,分别用 maPO方法和 AatapO方法分制字符串。用 mapO方法分削后,每个元素对应返回一个迷代器,即数组。fatNapO方法在进行同 mapO方法一样的操作后,将3个选代器的元素扁平化(压成同一级别),保存在新 RDD 中
3.5 使用take()方法查询值
take(N)方法用于获取RDD的前N个元素,返回数据为数组。take()与collect()方法的原理相似,collect()方法用于获取全部数据,take()方法获取指定个数的数据。获取RDD的前5个元素
3.6 使用union()方法合并RDD
union()方法是一种转换操作,用于将两个RDD合并成一个,不进行去重操作,而且两个RDD中每个元素中的值的个数、数据类型需要保持一致。
3.7 filter()方法进行过滤
filter()方法是一种转换操作,用于过滤RDD中的元素。
filter()方法需要一个参数,这个参数是一个用于过滤的函数,该函数的返回值为Boolean类型。
filter()方法将返回值为true的元素保留,将返回值为false的元素过滤掉,最后返回一个存储符合过滤条件的所有元素的新RDD。
创建一个RDD,并且过滤掉每个元组第二个值小于等于1的元素。
3.8 使用distinct()方法去重
distinct()方法是一种转换操作,用于RDD的数据去重,去除两个完全相同的元素,没有参数。创建一个带有重复数据的RDD,并使用distinct()方法去重。
4、简单集合操作
4.1 intersection()方法
intersection()方法用于求出两个RDD的共同元素,即找出两个RDD的交集,参数是另一个RDD,先后顺序与结果无关。创建两个RDD,其中有相同的元素,通过intersection()方法求出两个RDD的交集
4.2 subtract()方法
subtract()方法用于将前一个RDD中在后一个RDD出现的元素删除,可以认为是求补集的操作,返回值为前一个RDD去除与后一个RDD相同元素后的剩余值所组成的新的RDD。两个RDD的顺序会影响结果。创建两个RDD,分别为rdd1和rdd2,包含相同元素和不同元素,通过subtract()方法求rdd1和rdd2彼此的补集。
4.3 cartesian()方法
cartesian()方法可将两个集合的元素两两组合成一组,即求笛卡儿积。创建两个RDD,分别有4个元素,通过cartesian()方法求两个RDD的笛卡儿积。
三、SparkSQL
1、SparkSQL简介
Spark SQL主要提供了以下三个功能:
1.Spark SQL可从各种结构化数据源中读取数据,进行数据分析。
2.Spark SQL包含行业标准的JDBC和ODBC连接方式,因此它不局限于在Spark程序内使用SQL语句进行查询。
3.Spark SQL可以无缝地将SQL查询与Spark程序进行结合,它能够将结构化数据作为Spark中的分布式数据集(RDD)进行查询。
2、查看DataFrame方法
查看及获取数据的常用函数或方法
方法 | 描述 |
printSchema | 打印数据模式 |
show | 查看数据 |
first/head/take/takeAsList | 获取若干行数据 |
collect/collectAsList | 获取所有数据 |
将movies.dat电影数据上传至HDFS中,加载数据为RDD并将其转换为DataFrame.
2.1 printSchema:输出数据模式
printSchema函数查看数据模式,打印出列的名称和类型
2.2 show():查看数据
方法 | 描述 |
show() | 显示前20条记录 |
show(x:Int) | 显示x条记录 |
show(truncate:Boolean) | 是否最多只显示20条记录,默认true |
show(x:Int,truncate:Boolean) | 显示x条记录并设置过长字符串的显示格式 |
show()方法与show(true)方法一样,只显示前20条记录并且最多只显示20个字符
若是要显示所有字符,需要使用show(false)方法
2.3 first()/head()/take()/takeAsList():获取若干条记录
方法 | 描述 |
first | 获取第一行记录 |
head(n:Int) | 获取前n行记录 |
take(n:Int) | 获取前n行记录 |
takeAsList(n:Int) | 获取前n行数据,并以列表的形式展现 |
2.4 collect()/collectAsList():获取所有数据
collect方法可以将DataFrame中的所有数据都获取到,并返回一个数组。
collectAsList方法可以获取所有数据,返回一个列表。
3、查询DataFrame方法
方法 | 描述 |
where | 条件查询 |
select/selectExpr/col/apply | 查询指定字段的数据信息 |
limit | 查询前n行记录 |
order by | 排序查询 |
group by | 分组查询 |
join | 连接查询 |