// TODO 算子 - flatMap
val rdd = sc.makeRDD(List(List(1,2),3,List(4,5)))
val flatRDD = rdd.flatMap(
data =>{
data match {case list:List[_]=> list
case dat =>List(dat)}})
flatRDD.collect().foreach(println)
glom
// TODO 算子 - glom
val rdd : RDD[Int]= sc.makeRDD(List(1,2,3,4),2)// List => Int// Int => Array
val glomRDD: RDD[Array[Int]]= rdd.glom()
glomRDD.collect().foreach(data=>println(data.mkString(",")))// TODO 算子 - glom
val rdd : RDD[Int]= sc.makeRDD(List(1,2,3,4),2)// 【1,2】,【3,4】// 【2】,【4】// 【6】
val glomRDD: RDD[Array[Int]]= rdd.glom()
val maxRDD: RDD[Int]= glomRDD.map(
array =>{
array.max
})println(maxRDD.collect().sum)
groupby
// TODO 算子 - groupBy
val rdd : RDD[Int]= sc.makeRDD(List(1,2,3,4),2)// groupBy会将数据源中的每一个数据进行分组判断,根据返回的分组key进行分组// 相同的key值的数据会放置在一个组中
def groupFunction(num:Int)={
num %2}
val groupRDD: RDD[(Int, Iterable[Int])]= rdd.groupBy(groupFunction)
groupRDD.collect().foreach(println)// TODO 算子 - groupBy
val rdd = sc.makeRDD(List("Hello","Spark","Scala","Hadoop"),2)// 分组和分区没有必然的关系
val groupRDD = rdd.groupBy(_.charAt(0))
groupRDD.collect().foreach(println)// TODO 算子 - groupBy
val rdd = sc.textFile("datas/apache.log")
val timeRDD: RDD[(String, Iterable[(String, Int)])]= rdd.map(
line =>{
val datas = line.split(" ")
val time =datas(3)//time.substring(0, )
val sdf = new SimpleDateFormat("dd/MM/yyyy:HH:mm:ss")
val date: Date = sdf.parse(time)
val sdf1 = new SimpleDateFormat("HH")
val hour: String = sdf1.format(date)(hour,1)}).groupBy(_._1)
timeRDD.map{case( hour, iter )=>{(hour, iter.size)}}.collect.foreach(println)
distinct
// TODO 算子 - distinct
val rdd = sc.makeRDD(List(1,2,3,4,1,2,3,4))
val rdd1: RDD[Int]= rdd.distinct()
rdd1.collect().foreach(println)
sortBy
// TODO 算子 - sortBy
val rdd = sc.makeRDD(List(6,2,4,5,3,1),2)
val newRDD: RDD[Int]= rdd.sortBy(num=>num)//按照num排序
newRDD.saveAsTextFile("output")// TODO 算子 - sortBy
val rdd = sc.makeRDD(List(("1",1),("11",2),("2",3)),2)// sortBy方法可以根据指定的规则对数据源中的数据进行排序,默认为升序,第二个参数可以改变排序的方式// sortBy默认情况下,不会改变分区。但是中间存在shuffle操作
val newRDD = rdd.sortBy(t=>t._1.toInt, false)//拿元组第一个来排,这里把字符串转为数字来排
newRDD.collect().foreach(println)
双Value类型
// TODO 算子 - 双Value类型// 交集,并集和差集要求两个数据源数据类型保持一致// 拉链操作两个数据源的类型可以不一致
val rdd1 = sc.makeRDD(List(1,2,3,4))
val rdd2 = sc.makeRDD(List(3,4,5,6))
val rdd7 = sc.makeRDD(List("3","4","5","6"))// 交集 : 【3,4】
val rdd3: RDD[Int]= rdd1.intersection(rdd2)//val rdd8 = rdd1.intersection(rdd7)println(rdd3.collect().mkString(","))// 并集 : 【1,2,3,4,3,4,5,6】
val rdd4: RDD[Int]= rdd1.union(rdd2)println(rdd4.collect().mkString(","))// 差集 : 【1,2】
val rdd5: RDD[Int]= rdd1.subtract(rdd2)println(rdd5.collect().mkString(","))// 拉链 : 【1-3,2-4,3-5,4-6】
val rdd6: RDD[(Int, Int)]= rdd1.zip(rdd2)
val rdd8 = rdd1.zip(rdd7)println(rdd6.collect().mkString(","))
(Key - Value类型)
reduceByKey
// TODO 算子 - (Key - Value类型)
val rdd = sc.makeRDD(List(("a",1),("a",2),("a",3),("b",4)))// reduceByKey : 相同的key的数据进行value数据的聚合操作// scala语言中一般的聚合操作都是两两聚合,spark基于scala开发的,所以它的聚合也是两两聚合// 【1,2,3】// 【3,3】// 【6】// reduceByKey中如果key的数据只有一个,是不会参与运算的。
val reduceRDD: RDD[(String, Int)]= rdd.reduceByKey((x:Int, y:Int)=>{println(s"x = ${x}, y = ${y}")
x + y
})
reduceRDD.collect().foreach(println)
groupByKey
// TODO 算子 - (Key - Value类型)
val rdd = sc.makeRDD(List(("a",1),("a",2),("a",3),("b",4)))// groupByKey : 将数据源中的数据,相同key的数据分在一个组中,形成一个对偶元组// 元组中的第一个元素就是key,// 元组中的第二个元素就是相同key的value的集合
val groupRDD: RDD[(String, Iterable[Int])]= rdd.groupByKey()
groupRDD.collect().foreach(println)
val groupRDD1: RDD[(String, Iterable[(String, Int)])]= rdd.groupBy(_._1)
join
// TODO 算子 - (Key - Value类型)
val rdd1 = sc.makeRDD(List(("a",1),("a",2),("c",3)))
val rdd2 = sc.makeRDD(List(("a",5),("c",6),("a",4)))// join : 两个不同数据源的数据,相同的key的value会连接在一起,形成元组// 如果两个数据源中key没有匹配上,那么数据不会出现在结果中// 如果两个数据源中key有多个相同的,会依次匹配,可能会出现笛卡尔乘积,数据量会几何性增长,会导致性能降低。
val joinRDD: RDD[(String,(Int, Int))]= rdd1.join(rdd2)
joinRDD.collect().foreach(println)(a,(1,5))(a,(1,4))(a,(2,5))(a,(2,4))(c,(3,6))
leftjoin rightjoin
// TODO 算子 - (Key - Value类型)
val rdd1 = sc.makeRDD(List(("a",1),("b",2)//, ("c", 3)))
val rdd2 = sc.makeRDD(List(("a",4),("b",5),("c",6)))//val leftJoinRDD = rdd1.leftOuterJoin(rdd2)
val rightJoinRDD = rdd1.rightOuterJoin(rdd2)//leftJoinRDD.collect().foreach(println)
rightJoinRDD.collect().foreach(println)
cogroup
// TODO 算子 - (Key - Value类型)
val rdd1 = sc.makeRDD(List(("a",1),("b",2)//, ("c", 3)))
val rdd2 = sc.makeRDD(List(("a",4),("b",5),("c",6),("c",7)//同一个数据源内部先group,然后不同数据源再进行连接))// cogroup : connect + group (分组,连接)
val cgRDD: RDD[(String,(Iterable[Int], Iterable[Int]))]= rdd1.cogroup(rdd2)
cgRDD.collect().foreach(println)// (a,(CompactBuffer(1),CompactBuffer(4)))// (b,(CompactBuffer(2),CompactBuffer(5)))// (c,(CompactBuffer(),CompactBuffer(6, 7)))
Action操作
countByKey, countByValues
//val rdd = sc.makeRDD(List(1,1,1,4),2)
val rdd = sc.makeRDD(List(("a",1),("a",2),("a",3)))// TODO - 行动算子//val intToLong: collection.Map[Int, Long] = rdd.countByValue() //统计每个value出现的次数//println(intToLong)
val stringToLong: collection.Map[String, Long]= rdd.countByKey()//统计每个key出现的次数println(stringToLong)//因为是map,所以可以直接println//wordcount// countByKey
def wordcount7(sc : SparkContext): Unit ={
val rdd = sc.makeRDD(List("Hello Scala","Hello Spark"))
val words = rdd.flatMap(_.split(" "))
val wordOne = words.map((_,1))
val wordCount: collection.Map[String, Long]= wordOne.countByKey()}// countByValue
def wordcount8(sc : SparkContext): Unit ={
val rdd = sc.makeRDD(List("Hello Scala","Hello Spark"))
val words = rdd.flatMap(_.split(" "))
val wordCount: collection.Map[String, Long]= words.countByValue()}
文章目录flatMapglomgroupbydistinctsortBy双Value类型(Key - Value类型)reduceByKeygroupByKeyflatMap // TODO 算子 - flatMapval rdd = sc.makeRDD(List(List(1,2),3,List(4,5))) val flatRDD = rdd.flatMap( data => { data match {