首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >map和flatMap之间的区别是什么,它们的一个很好的用例是什么?

map和flatMap之间的区别是什么,它们的一个很好的用例是什么?
EN

Stack Overflow用户
提问于 2014-03-12 19:54:27
回答 8查看 207.7K关注 0票数 285

谁能给我解释一下map和flatMap之间的区别,以及它们最好的用例是什么?

“扁平化结果”是什么意思?它有什么好处?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2014-03-19 23:21:24

以下是作为spark-shell会话的不同之处的示例:

首先,一些数据-两行文本:

代码语言:javascript
复制
val rdd = sc.parallelize(Seq("Roses are red", "Violets are blue"))  // lines

rdd.collect

    res0: Array[String] = Array("Roses are red", "Violets are blue")

现在,map将一个长度为N的RDD转换为另一个长度为N的RDD。

例如,它从两行映射到两行长度:

代码语言:javascript
复制
rdd.map(_.length).collect

    res1: Array[Int] = Array(13, 16)

但是flatMap (不严格地说)将长度为N的RDD转换为N个集合的集合,然后将这些集合展平为结果的单个RDD。

代码语言:javascript
复制
rdd.flatMap(_.split(" ")).collect

    res2: Array[String] = Array("Roses", "are", "red", "Violets", "are", "blue")

我们每行有多个单词,并且有多行,但是我们最终得到了一个单词的输出数组

为了说明这一点,从行集合到单词集合的flatMapping如下所示:

代码语言:javascript
复制
["aa bb cc", "", "dd"] => [["aa","bb","cc"],[],["dd"]] => ["aa","bb","cc","dd"]

因此,对于flatMap,输入和输出的RDDs通常具有不同的大小。

如果我们试图将map与我们的split函数一起使用,我们最终会得到嵌套结构(单词数组的RDD,类型为RDD[Array[String]]),因为我们必须在每个输入中只有一个结果:

代码语言:javascript
复制
rdd.map(_.split(" ")).collect

    res3: Array[Array[String]] = Array(
                                     Array(Roses, are, red), 
                                     Array(Violets, are, blue)
                                 )

最后,一个有用的特例是映射到一个可能不返回答案的函数,因此返回一个Option。我们可以使用flatMap过滤掉返回None的元素,并从返回Some的元素中提取值

代码语言:javascript
复制
val rdd = sc.parallelize(Seq(1,2,3,4))

def myfn(x: Int): Option[Int] = if (x <= 2) Some(x * 10) else None

rdd.flatMap(myfn).collect

    res3: Array[Int] = Array(10,20)

(请注意,此处选项的行为非常类似于包含一个元素或零个元素的列表)

票数 210
EN

Stack Overflow用户

发布于 2014-04-24 21:46:55

如果您正在询问Spark中RDD.map和RDD.flatMap之间的区别,map会将一个大小为N的RDD.map转换为另一个大小为N的RDD。例如:

代码语言:javascript
复制
myRDD.map(x => x*2)

例如,如果myRDD由Double组成。

而flatMap可以将RDD转换为另一个不同大小的RDD:

代码语言:javascript
复制
myRDD.flatMap(x =>new Seq(2*x,3*x))

将返回大小为2*N的RDD或

代码语言:javascript
复制
myRDD.flatMap(x =>if x<10 new Seq(2*x,3*x) else new Seq(x) )
票数 18
EN

Stack Overflow用户

发布于 2016-06-17 15:41:27

test.md为例:

代码语言:javascript
复制
➜  spark-1.6.1 cat test.md
This is the first line;
This is the second line;
This is the last line.

scala> val textFile = sc.textFile("test.md")
scala> textFile.map(line => line.split(" ")).count()
res2: Long = 3

scala> textFile.flatMap(line => line.split(" ")).count()
res3: Long = 15

scala> textFile.map(line => line.split(" ")).collect()
res0: Array[Array[String]] = Array(Array(This, is, the, first, line;), Array(This, is, the, second, line;), Array(This, is, the, last, line.))

scala> textFile.flatMap(line => line.split(" ")).collect()
res1: Array[String] = Array(This, is, the, first, line;, This, is, the, second, line;, This, is, the, last, line.)

如果你使用map方法,你会得到test.md的行数,对于flatMap方法,你会得到单词的数量。

map方法类似于flatMap,它们都返回一个新的RDD。map方法经常使用return一个新的RDD,flatMap方法经常使用分词。

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22350722

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档