`map`和`reduce`方法如何在Spark RDD中工作?

Des*_*PRG 18 closures scala apache-spark

以下代码来自Apache Spark的快速入门指南.有人可以解释一下"线"变量是什么以及它来自何处?

textFile.map(line => line.split(" ").size).reduce((a, b) => if (a > b) a else b)
Run Code Online (Sandbox Code Playgroud)

另外,如何将值传递给a,b?

链接到QSG http://spark.apache.org/docs/latest/quick-start.html

Mar*_*nne 70

首先,根据你的链接, textfile创建为

val textFile = sc.textFile("README.md")
Run Code Online (Sandbox Code Playgroud)

使得textfileRDD[String]这意味着它是一个类型的弹性分布的数据集String.要访问的API与常规Scala集合的API非常相似.

那么现在是什么呢 map做什么?

想象一下,你有一份清单 String s并希望将其转换为Int列表,表示每个String的长度.

val stringlist: List[String] = List("ab", "cde", "f")
val intlist: List[Int] = stringlist.map( x => x.length )
Run Code Online (Sandbox Code Playgroud)

map方法需要一个函数.一个功能,来自String => Int.使用该函数,列表的每个元素都会被转换.所以intlist的价值是List( 2, 3, 1 )

在这里,我们创建了一个匿名函数String => Int.那是x => x.length.甚至可以将函数更明确地编写为

stringlist.map( (x: String) => x.length )  
Run Code Online (Sandbox Code Playgroud)

如果你确实使用上面的显式,你可以

val stringLength : (String => Int) = {
  x => x.length
}
val intlist = stringlist.map( stringLength )
Run Code Online (Sandbox Code Playgroud)

所以,这里绝对是显而易见的,那就是stringLength从功能StringInt.

备注:一般来说,map是一个所谓的Functor.当您提供A => B map的函数时,函子(此处为List)允许您使用该函数List[A] => List[B].这称为提升.

你的问题的答案

什么是"线"变量?

如上所述,line是函数的输入参数line => line.split(" ").size

更明确 (line: String) => line.split(" ").size

示例:如果line是"hello world",则函数返回2.

"hello world" 
=> Array("hello", "world")  // split 
=> 2                        // size of Array
Run Code Online (Sandbox Code Playgroud)

如何将值传递给a,b?

reduce还期望一个函数(A, A) => A,A你的类型在哪里RDD.让我们调用这个函数op.

是什么reduce.例:

List( 1, 2, 3, 4 ).reduce( (x,y) => x + y )
Step 1 : op( 1, 2 ) will be the first evaluation. 
  Start with 1, 2, that is 
    x is 1  and  y is 2
Step 2:  op( op( 1, 2 ), 3 ) - take the next element 3
  Take the next element 3: 
    x is op(1,2) = 3   and y = 3
Step 3:  op( op( op( 1, 2 ), 3 ), 4) 
  Take the next element 4: 
    x is op(op(1,2), 3 ) = op( 3,3 ) = 6    and y is 4
Run Code Online (Sandbox Code Playgroud)

这里的结果是列表元素的总和,10.

备注:一般reduce计算

op( op( ... op(x_1, x_2) ..., x_{n-1}), x_n)
Run Code Online (Sandbox Code Playgroud)

完整的例子

首先,文本文件是RDD [String],比如说

TextFile
 "hello Tyth"
 "cool example, eh?"
 "goodbye"

TextFile.map(line => line.split(" ").size)
 2
 3
 1
TextFile.map(line => line.split(" ").size).reduce((a, b) => if (a > b) a else b)
 3
   Steps here, recall `(a, b) => if (a > b) a else b)`
   - op( op(2, 3), 1) evaluates to op(3, 1), since op(2, 3) = 3 
   - op( 3, 1 ) = 3
Run Code Online (Sandbox Code Playgroud)


Tyt*_*yth 7

Map并且reduce是RDD类的方法,其具有类似于scala集合的接口.

你传递给方法的是什么map,reduce实际上是匿名函数(在map中有一个param,在reduce中有两个参数).textFile调用为每个元素(在此上下文中的文本行)提供了函数.

也许你应该首先阅读一些scala集合介绍.

您可以在此处阅读有关RDD类API的更多信息:https: //spark.apache.org/docs/1.2.1/api/scala/#org.apache.spark.rdd.RDD