下面的实验全部在spark-shell中运行即可
#-------------------------------------------------------------------------
HDFS到HDFS过程

看看map 和flatmap的位置

spark dataframe 调优 spark dataframe flatmap_spark dataframe 调优

Flatmap 和map 的定义
map()是将函数用于RDD中的每个元素,将返回值构成新的RDD。

flatmap()是将函数应用于RDD中的每个元素,将返回的迭代器的所有内容构成新的RDD

例子:

val rdd = sc.parallelize(List(“coffee panda”,“happy panda”,“happiest panda party”))

输入

rdd.map(x=>x).collect

结果

res9: Array[String] = Array(coffee panda, happy panda, happiest panda party)

输入

rdd.flatMap(x=>x.split(" ")).collect

结果

res8: Array[String] = Array(coffee, panda, happy, panda, happiest, panda, party)

flatMap说明白就是先map然后再flat,再来看个例子

scala>val rdd1 = sc.parallelize(List(1,2,3,3))
scala> rdd1.map(x=>x+1).collect

res10: Array[Int] = Array(2, 3, 4, 4)

scala> rdd1.flatMap(x=>x.to(3)).collect

res11: Array[Int] = Array(1, 2, 3, 2, 3, 3, 3)

map(func)
将原数据的每个元素传给函数func进行格式化,返回一个新的分布式数据集。(原文:Return a new distributed dataset formed by passing each element of the source through a function func.)

flatMap(func)
跟map(func)类似,但是每个输入项和成为0个或多个输出项(所以func函数应该返回的是一个序列化的数据而不是单个数据项)。(原文:Similar to map, but each input item can be mapped to 0 or more output items (so func should return a Seq rather than a single item).)

Flatmap 和map 使用说明
在使用时map会将一个长度为N的RDD转换为另一个长度为N的RDD;而flatMap会将一个长度为N的RDD转换成一个N个元素的集合,然后再把这N个元素合成到一个单个RDD的结果集。

比如一个包含三行内容的数据文件“README.md”。

在spark中map函数和flatMap函数是两个比较常用的函数。其中
map:对集合中每个元素进行操作。
flatMap:对集合中每个元素进行操作然后再扁平化。

例如:

val arr=sc.parallelize(Array(("A",1),("B",2),("C",3)))
arr.flatmap(x=>(x._1+x._2)).foreach(println)

输出结果为

A1

B2

C3

如果用map

val arr=sc.parallelize(Array(("A",1),("B",2),("C",3)))
arr.map(x=>(x._1+x._2)).foreach(println)

输出结果

A1

B2

C3

所以flatMap扁平化意思大概就是先用了一次map之后对全部数据再一次map。

Flatmap 和map 实际使用场景
有一个场景,在字符串中如何统计相邻字符对出现的次数。意思就是如果有A;B;C;D;B;C字符串,则(A,B),(C,D),(D,B)相邻字符对出现一次,(B,C)出现两次。

统计相邻字符对出现次数代码如下

scala>  val data="A;B;C;D;B;D;C;B;D;A;E;D;C;A;B"
scala> val data_rdd=sc.parallelize(List(data))
scala> data_rdd.map(_.split(";")).flatMap(x=>{ for(i<-0 until x.length-1) yield (x(i)+","+x(i+1),1)  }).reduceByKey(_+_).foreach(println)

输出结果为

(E,D,1)
(C,A,1)
(A,E,1)
(B,D,2)
(D,B,1)
(A,B,2)
(C,D,1)
(D,C,2)
(C,B,1)
(D,A,1)
(B,C,1)

其中
+

表示任选两个不重叠的相邻的元素
map操作我记得的有map(一条对一条),mapToPair(map成键值对),flatMap(一条记录变n条(n>=0))

Flatmap 和map 区别

map(func)函数会对每一条输入进行指定的func操作,然后为每一条输入返回一个对象;而flatMap(func)也会对每一条输入进行执行的func操作,然后每一条输入返回一个相对,但是最后会将所有的对象再合成为一个对象;从返回的结果的数量上来讲,map返回的数据对象的个数和原来的输入数据是相同的,而flatMap返回的个数则是不同的。

spark dataframe 调优 spark dataframe flatmap_scala_02

map函数会对每一条输入进行指定的操作,然后为每一条输入返回一个对象;而flatMap函数则是两个操作的集合——正是“先映射后扁平化”:

操作1:同map函数一样:对每一条输入进行指定的操作,然后为每一条输入返回一个对象

操作2:最后将所有对象合并为一个对象

通过上图可以看出,flatMap其实比map多的就是flatten操作。