次のコードは、Apache Sparkのクイックスタートガイドからのものです。 「ライン」変数とは何か、どこから来たのかを誰かに説明してもらえますか?
textFile.map(line => line.split(" ").size).reduce((a, b) => if (a > b) a else b)
また、値はどのようにa、bに渡されますか?
QSGへのリンク http://spark.Apache.org/docs/latest/quick-start.html
まず、リンクに従って、textfile
が次のように作成されます。
val textFile = sc.textFile("README.md")
textfile
はRDD[String]
であり、String
型の復元力のある分散データセットであることを意味します。アクセスするAPIは、通常のScalaコレクションのAPIと非常によく似ています。
map
は何をするのでしょうか?String
sのリストがあり、それを各ストリングの長さを表すIntsのリストに変換したいとします。
val stringlist: List[String] = List("ab", "cde", "f")
val intlist: List[Int] = stringlist.map( x => x.length )
map
メソッドには関数が必要です。 String => Int
からの関数。この関数を使用すると、リストの各要素が変換されます。したがって、intlistの値はList( 2, 3, 1 )
です
ここでは、String => Int
から匿名関数を作成しました。それはx => x.length
です。関数をより明示的に書くこともできます
stringlist.map( (x: String) => x.length )
上記の明示的な記述を使用する場合、次のことができます。
val stringLength : (String => Int) = {
x => x.length
}
val intlist = stringlist.map( stringLength )
したがって、ここでは、stringLengthがString
からInt
までの関数であることは明らかです。
備考:一般的に、map
はいわゆるファンクターを構成します。 A => Bから関数を提供する一方で、ファンクター(ここのリスト)のmap
を使用すると、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
値はどのように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
ここでの結果は、リスト要素の合計10です。
備考:一般的にreduce
は計算します
op( op( ... op(x_1, x_2) ..., x_{n-1}), x_n)
まず、テキストファイルは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
Map
およびreduce
はRDDクラスのメソッドであり、scalaコレクションに類似したインターフェースを持っています。
メソッドmap
およびreduce
に渡すものは、実際には匿名関数です(mapに1つのパラメーターがあり、reduceに2つのパラメーターがあります)。 textFile
は、含まれるすべての要素(このコンテキストのテキストの行)に対して提供された関数を呼び出します。
おそらく、最初にscalaコレクションの紹介を読んでください。
RDDクラスAPIの詳細については、こちらをご覧ください: https://spark.Apache.org/docs/1.2.1/api/scala/#org.Apache.spark.rdd.RDD
map関数が行うことは、引数のリストを受け取り、それを何らかの関数にマップすることです。精通している場合、Pythonのマップ関数に似ています。
また、Fileは文字列のリストのようなものです。 (正確ではありませんが、それが反復されている方法です)
これがあなたのファイルだと考えてみましょう。
val list_a: List[String] = List("first line", "second line", "last line")
それでは、map関数がどのように機能するかを見てみましょう。
list of values
既に持っているものとfunction
この値をマッピングしたいもの。理解のために本当に簡単な関数を考えてみましょう。
val myprint = (arg:String)=>println(arg)
この関数は、単純に単一の文字列引数を取り、コンソールに出力します。
myprint("hello world")
hello world
この関数をリストに一致させると、すべての行が出力されます
list_a.map(myprint)
以下で説明するように、同じことを行う匿名関数も作成できます。
list_a.map(arg=>println(arg))
あなたの場合、line
はファイルの最初の行です。引数名は好きなように変更できます。たとえば、上記の例では、arg
をline
に変更しても問題なく動作します
list_a.map(line=>println(line))