Spark RDD篇

本文详细介绍了Spark RDD的创建和转换操作,包括map、filter、flatMap等,以及行动操作如reduce、collect、count等。此外,还讲解了groupByKey、reduceByKey、join等聚合和连接操作,帮助理解Spark数据处理的基本流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

记录在学习大数据技术过程中的学习笔记

目录

Spark RDD 创建操作

Spark RDD 转换操作

map

filter

flatMap

mapPartitions

mapPartitionsWithIndex

sample

union

groupByKey

reduceByKey

aggregateByKey

combineByKey

sortByKey

join

Spark RDD 行动操作

rduce

collect

count

first

take

takeSample

takeOrdered

saveAsTextFile

countByKey

foreach


Spark RDD 创建操作

val data = Array(1,2,3,4,5,6,7,8)
val distData = sc.parallelize(data,3)

外部数据源来创建

//本地当前目录下文件
val distFile1 = sc.textFile("data.txt")

//HDFS文件
val distFile2 = sc.textFile("hdfs://192.168.10.100/input/data.txt")

//本地指定目录下文件
val distFile3 = sc.textFile("file:/input/data.txt")

//本地指定目录下文件
val distFile4 = sc.textFile("/input/data.txt")

注意:textFile可以读取多个文件,或者一个文件夹,也支持压缩文件、包含通配符的路径

//读取多个文件
textFile("/input/001.txt,/input/002.txt")

//读取目录
textFile("/input")

//含通配符的路径
textFile("/input/*.txt")

//读取压缩文件
textFile("/input/*.gz")

Spark RDD 转换操作

map

map是对RDD中的每个元素都执行一个指定的函数来产生新的RDD;RDD之间的元素是一对一关系;

val conf = new SparkConf().setAppName("rdd_1").setMaster("local")
val sc = new SparkContext(conf)

sc.parallelize(1 to 10) //创建rdd(1~10)
   .map(_*2)             //对rdd中的每个元素 * 2
   .foreach(println)     //打印rdd中的所有元素

----------结果----------
2
4
6
8
10
12
14
16
18
20
-------------------------

filter

Filter是对RDD元素进行过滤;返回一个新的数据集,是经过func函数后返回为true的原元素组成

sc.parallelize(1 to 10)    创建rdd(1~10)
   .filter(_ > 5)          过滤掉小于5的rdd元素
   .foreach(println)       打印rdd中所有元素

---------------结果---------------
6
7
8
9
10
----------------------------------

flatMap

flatMap类似于map,但是每一个输入元素,会被映射到多个输出元素(因此,func函数的返回值是一个Seq),而不是单一的元素,rdd之间的元素是一对多的关系

也就是说进去一个元素,可以出来多个元素

sc.parallelize(1 to 2)    //创建rdd(1~2)
      .flatMap(_ to 2)    //对每个进入的rdd元素,返回 自己 到 2 的数组
      .foreach(println)   //打印所有元素

-----------结果----------
1
2
2
-------------------------

mapPartitions

mapPartitions是map的一个变种。map的输入函数是应用于RDD中每个元素,而mapPartitions的输入函数是每个分区的数据,也就是把每个分区中的内容作为整体来处理

mapPartitionsWithIndex

mapPartitionsWithSpilt与mapPartitions的功能类似,只是多传入split index而已,所有func函数是(Int,Iterator<T>)=> Iterator<U>类型

sample

sample(withReplacement,fraction,seed)是根据给定的随机种子seed,随机抽样出frac的数据。withReplacement:是否放回抽样;

fraction:比例,0.1表示10%

sc.parallelize(1 to 100)        //创建rdd(1~100)
      .sample(false, 0.1, 0)    //抽样10%,种子号 0
      .foreach(println)         //打印所有rdd

----------------结果----------------
10
39
41
53
54
58
60
80
89
98
-------------------------------------

union

union(otherDataset)是数据合并,返回一个新的数据集,由原数据集和otherDataset联合而成

sc.parallelize(1 to 5)             //创建rdd1(1~5)
      .union(                      //联合
        sc.parallelize(6 to 10     //创建rdd2(6~10)
        ))
      .foreach(println)            //打印

--------------------结果--------------------
1
2
3
4
5
6
7
8
9
10
---------------------------------------------

groupByKey

groupByKey([numTasks])是数据分组操作,在一个由(k,v)对组成的数据集上调用,返回一个(K,Seq[V])对的数据集。

 val rdd = sc
.parallelize(Array("小明" -> "age:20" ,"小明" -> "语文:60","小明" -> "数学:70","小明" -> "英语:85"))    //创建rdd (k,v) 键值对

    rdd.groupByKey()        //根据k(小明)分组
      .foreach(line => {    //遍历rdd
        println(line._1)    //打印k
        println(line._2)    //打印v
      })

-----------------------结果-----------------------
小明
CompactBuffer(age:20, 语文:60, 数学:70, 英语:85)
--------------------------------------------------

reduceByKey

reduceByKey(func,[numTasks])是数据分组聚合操作,在一个(k,v)对的数据集上使用,返回一个(k,v)对的数据集,key相同的值,都被使用指定的reduce函数聚合到一起

sc.parallelize(Array("k" -> 1,"k" -> 2,"k1" -> 2,"k1" -> 3))  //创建rdd(k,v)键值对
      .reduceByKey(_+_)                //对相同的k进行聚合,对相同的k进行求和
      .foreach(line => {               //遍历
        println(line._1,line._2)       //打印(k,v)键值对
      })

------------------结果-------------------
(k,3)
(k1,5)
-----------------------------------------

aggregateByKey

aggreateByKey(zeroValue:U)(seqOp:(U,T)) => U,combOp:(U,U) => U) 和 reduceByKey的不同在于,reduceByKey输入输出都是(K,V),而aggreateByKey输出是(K,U),可以不同于输入(K,V),aggreateByKey的三个参数:

zeroValue:U ,初始值,比如空列表

seqOp:(U,T) => U,seq操作符,描述如何将T合并入U,比如如何将item合并到列表;

combOp:(U,U) => U,comb操作符,描述如何合并两个U,比如合并连个列表;

所以aggreateByKey可以看成更高抽象的,更灵活的reduce或group。

combineByKey

combineByKey是对RDD中的数据集按照Key进行聚合操作。聚合操作的逻辑通过自定义函数提供combineByKey。

combineByKey[C](createCombiner:(V)) => C,mergeValue:(C,V)  => C,mergeCombiner:(C,C)

=> C,numPartitions:Int):RDD[(K,C)]类型的RDD转换为(K,C)类型的RDD,C和V可以不一样。

sortByKey

sortBykey([ascending],[numTasks])是排序操作,对(k,v)类型的数据按照K进行排序,其中K需要实现Ordered方法

     sc.parallelize(Array(3 -> "v",2 -> "v",4 -> "v",1 -> "v"))
      .sortByKey()        //按k排序
      .foreach(println)

----------------结果------------------
(1,v)
(2,v)
(3,v)
(4,v)
--------------------------------------

join

join(otherDataset,[numTasks])是连接操作,根据k连接两个rdd

    val rdd1 = sc.parallelize(Array(("k",1),("k1",2)))
    val rdd2 = sc.parallelize(Array(("k",3),("k1",4)))
    rdd1
      .join(rdd2)            //连接两个rdd
      .foreach(println)

-----------------结果-------------------
(k,(1,3))
(k1,(2,4))
----------------------------------------

Spark RDD 行动操作

rduce

reduce(func)是对数据集的所有元素执行聚集(func)函数,该函数必须是可交换的。

    println(
      sc.parallelize(1 to 10)
      .reduce(_+_)            //聚合操作,求和
    )

----------------结果---------------
55
-----------------------------------

collect

collect是将数据集的所有元素以一个array的形式返回

    sc.parallelize(1 to 5)
      .collect()            //返回一个数组
      .foreach(println(_))

---------------结果-------------
1
2
3
4
5
--------------------------------

count

count 统计rdd元素中的个数

    val value = sc.parallelize(Array(1,2,3))
    println(
      value
        .count()    //统计个数
    )

----------------结果----------
3
------------------------------

first

返回rdd中第一个元素

println(
  sc.parallelize(Array(1,2,3,4,5))
    .first()        // 返回rdd 中的第一个元素
)

-------------结果--------------
1
-------------------------------

take

返回前n个元素

    sc.parallelize(Array(1,2,3,4,5,6))
      .take(3)            //返回前n个元素
      .foreach(println)

----------------结果----------------
1
2
3
-----------------------------------

takeSample

返回包含随机的num个元素的数组,和Sample不同,takeSample是行动操作,所以返回的是数组而不是RDD,其中第一个参数withReplacement是抽样时是否放回,第二个参数num会精确指定抽样数,而不是比例。

    sc.parallelize(1 to 10)
      .takeSample(true,5)        //开启随机抽样,抽取5个
      .foreach(println)

-------------结果------------
4
7
4
3
6
-----------------------------

takeOrdered

返回包含随机的n个元素的数组,按照顺序输出

    sc.parallelize(1 to 10)
      .takeOrdered(5)        //随机抽取5个
      .foreach(println)

--------------结果-------------
1
2
3
4
5
-------------------------------

saveAsTextFile

把数据集中的元素写到一个文本文件,Spark会对每个元素调用toString方法来把每个元素存成文本文件的一行

countByKey

对于(K,V)类型的RDD,返回一个(K,Int)的map,Int为K的个数

foreach

foreach(func)时数据集中的每个元素都执行func函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值