スパークでスカラ

夜の睡眠、スカラ座のいくつかの基本的な動作の概要を立ち上げ、疲労から回復する話

打包MVNスカラ:コンパイル&& MVNパッケージ

1、RDDを作成 - テキストファイルを並列+(makeRDD)

 

# 创建textFileRDD
val textFile = sc.textFile("README.md")
textFile.first()  #获取textFile RDD的第一个元素
res3:String = # Apache Spark

# 筛选出包括Spark关键字的RDD然后进行行计数
val  linesWithSpark = textFile.filter(line => line.contains("Spark"))
linesWithSpark.count()
res10:Long = 19

# 找出RDD textFile中包含单词数最多的行
textFile.map(line=>line.split(" ").size).reduce((a,b)=>Math.max(a,b))
res12:Int = 14  #第14行是包含单词最多的行

# 在scala shell中引入Java方法:
import java.lang.Math
textFile.map(line=>line.split(" ").size).reduce((a,b) => Math.max(a,b))

#将RDD linesWithSpark 缓存,然后进行计数
linesWithSpark.cache()
res13:linesWithSpark.type = 
MapPartitionsRDD[8] at filter at <console>:23
linesWithSpark.count()
res15:Long = 19

RDD:
makeRDDと同じを並列化が、それは唯一のmakeRDD Scalaの使用と思われる、PythonとRを使用することができます並列化

 

 

# 通过单词列表集合创建RDD thingsRDD
val thingsRDD = sc.parallelize(List("spoon","fork","plate","cup","bottle"))

# 计算RDD thingsRDD中单词的个数
thingsRDD.count()
res16:Long = 5

2、groupByKey

 

 

def groupByKey():RDD[( K, Iterable[V]) ]
def groupByKey(numPartitions:Int):RDD[(K, Iterable[V])]
def groupByKey(partitioner:Partitioner):RDD[(K,Iterable[v])]

この関数RDD [K、V] Vは、各K値のIterableのセットに対応する[V]で、

  numPartitionsは、パーティションの数を指定し、
  パーティショナは、パーティション関数を指定します。

 

 

  var rdd1 = sc.makeRDD(Array(("A",0),("A",2),("B",1),("B",2),("C",1)))

  println(rdd1.groupByKey().collect.toBuffer) 
  //ArrayBuffer((A,CompactBuffer(0, 2)), (B,CompactBuffer(1, 2)), (C,CompactBuffer(1)))

3、reduceByKey

 

def reduceBykey(func:(V,V)=>V):RDD[(K,V)]
def reduceByKey(func:(V,V)=>V),numPartitions:Int):RDD[(K,V)]
def reduceByKey(partitioner:Partitioner, func:(V,V)=>V):RDD[(K,V)]

この関数は、マッピング関数に従って計算されるRDDは[Kは、V]はVが各K値に対応するために使用されます。

  パーティションの数を指定するためのnumPartitions;
  パラメータは、パーティのパーティション関数を指定します。

 

 

var rdd1 = sc.makeRDD(Array(("A",0),("A",2),("B",1),("B",2),("C",1)))

rdd1.partitions.size //Int = 15

var rdd2 = rdd1.reduceByKey((x,y)=>x+y)

rdd2.collect
//Array[(String,Int)] = Array((A,2),(B,3),(C,1))

rdd2.partitions.size
// Int = 4

var rdd2 = rdd1.reduceByKey(new org.apache.spark.HashPartitioner(2),(x,y)=>x+y)

rdd2.collect
//Array[(String, Int)] = Array((B,3),(A,2),(C,1))

rdd2.partitions.size
//Int =2

4、reduceByKeyLocally

 

 

def reduceByKeyLocally(func:(V,V)=>V):Map[K,V]

この関数は、RDD [K、V] Vは、マッピング関数に従って各Kに対応する値が算出され、算出結果の代わりにRDD [K、V]の地図[K、V]にマッピングされます。

 

 

    var rdd1__ = sc.makeRDD(Array(("A",0),("A",2),("B",1),("B",2),("C",1)))
    println(rdd1__.reduceByKeyLocally((x,y)=>x+y))
//    Map(A -> 2, B -> 3, C -> 1)
//    scala.collection.Map[String,Int] = Map(B->3,A->2,C->1)

5、groupByKey countByKey countByValue reduceByKey

val d = sc.makeRDD(Array(1,2,3,4,5,1,3,5))
val dd = d.map(x=>(x,1))  //构造pair RDD, dd:RDD[(Int,Int)]
结果:ArrayBuffer((1,1), (2,1), (3,1), (4,1), (5,1), (1,1), (3,1), (5,1))


5.1  groupByKey
val dg = dd.groupByKey()  //dg :RDD[(Int, Iterable[Int])]   dg: ArrayBuffer((4,CompactBuffer(1)), (1,CompactBuffer(1, 1)), (5,CompactBuffer(1, 1)), (2,CompactBuffer(1)), (3,CompactBuffer(1, 1)))
val dgc = dg.collectAsMap //dgc:Map[Int, Iterable[Int]]   Map(2 -> CompactBuffer(1), 5 -> CompactBuffer(1, 1), 4 -> CompactBuffer(1), 1 -> CompactBuffer(1, 1), 3 -> CompactBuffer(1, 1))
val dgci = dgc.foreach(println(_))
结果输出
(2,CompactBuffer(1))
(5,CompactBuffer(1, 1))
(4,CompactBuffer(1))
(1,CompactBuffer(1, 1))
(3,CompactBuffer(1, 1))

5.2 countByKey

 

 

val dk = dd.countByKey()  //dk: Map[Int, Long]
dk.foreach(println(_))
(5,2) //key为5出现了2次
(1,2) //key为1出现了2次
(2,1) //key为2出现了1次
(3,2) //key为3出现了2次

5.3 countByValue

 

 

val dv = dd.countByValue()  // dv: Map[(Int, Int),Long]
dv.foreach(println(_))      
//output
((5,1),2)
((3,1),2)
((4,1),1)
((1,1),2)
((2,1),1)

5.4 reduceByKey

 

 

    val rdd = sc.parallelize(List(
            (("a"), 1.0),
            (("a"), 3.0),
            (("a"), 2.0),
      (("b"),4.0)
    ))
    val reduceByKey = rdd.reduceByKey((a , b) => a+b)
    //reduceByKey:RDD[(String,Double)]
    reduceByKey.collect().foreach(println(_))
//(a,6.0)
//(b,4.0) 

6減らします

reduceRight前記reduceLeftセット動作の終了から始まるセット開始操作から動作と、元ヘッドの両方を減少させます。

 

val list = List(1,2,3,4,5)

list.reduceLeft(_ + _) //15

list.reduceRight(_ + _) //15

reduceLeft(_ _ +)は、両方の2つの要素の加算操作にリストヘッドの開始を示し、下線がプレースホルダです。削減する。このとき、同等

 

1+2 = 3
3+3 = 6
6+4 = 10
10+5 = 15

リストの最後からreduceRight(_ _ +)が開始されると、加算動作二十から二の要素

 

4+5 = 9
3+9 = 12
2+12 = 14
1+14 = 15

異なるセキュリティの減算効果のために

 

val list = List(1,2,3,4,5)

list.reduceLeft(_ - _) //-13

list.reduceRight(_ - _) //3

新しい値を生成しながら、RDD入力機能に転送要素二十から二を低減する、新たに生成されたRDDの値は、次の要素は、最後だけ関数値まで入力に送信されます。

val rdd = sc.parallelize(1 to 10)
rdd.reduce((x, y) => x + y) //55

ここでは、コントラストreduceByKey

値はKVのRDDキー要素の要素等reduceByKeyを低減することであり、したがって、複数の要素の値は、新たなペアを形成するために、値は、元のRDD鍵KVを低減するために同じキーです。

 

val rdd = sc.parallelize(List((1,2),(3,4),(3,6)))
rdd.reduceByKey((x,y) => x + y).collect
// Array[(Int, Int)] = Array((1,2), (3,10))

二つの重要な要素3は、(3,10)に変換されるため、したがって要素のような値キーを加算、および

 

7倍

折りたたみ式(折りたたみ)操作と削減(削減)操作が比較的似ています。動作は、最初の「シード」値を起動し、値のコンテキストには、収集プロセス中の各素子からの倍を必要とします。

scala> val list = List(1,2,3,4,5)
 
scala> list.fold(10)(_*_)
res0: Int = 1200

リスト乗算演算のすべての要素に疲れて機能の実装を折ります。折り畳み機能は、他のパラメータが関数の累積的な結果を計算するために使用され、1つのパラメータはここで、10初期シード値であり、2つのパラメータをとり、これは乗法です。list.fold(10)(パフォーマンス*それらが値10を得るために)、最初の初期値およびリスト1乗算演算の最初の値をとり、乗算し、次いで10に蓄積された乗算値とのリストを聞かせ第二の値が2乗算演算である、ように値20を取り、そして、最終的な結果乗法1200を取得するために疲れてきましたます。左から右へ、foldLeft()、第1のパラメータ値の方向が蓄積され、コレクションがトラバースされるfoldLeft()およびfoldRight():倍二つの変種を有します。foldRight()、2番目のパラメータは、累積値であり、トラバーサルのセットは、右から左へです。

foldByKeyは、以下の

 

val rdd1 = sc.parallelize(List("dog", "wolf", "cat", "bear"), 2)
val rdd2 = rdd1.map(x => (x.length, x)) //Array[(Int, String)] = Array((3,dog), (4,wolf), (3,cat), (4,bear)
val rdd3 = rdd2.foldByKey("")(_+_) //Array[(Int, String)] = Array((4,wolfbear), (3,dogcat))

8参加

 

DEF [W]を参加(他:RDD [(K、W)]):RDD [(K、(V、W))]

DEF [W]を参加(他:RDD [(K、W)]、numPartitions:INT):RDD [(K、(V、W))]

RDD [(F(V、W))]:[W](:RDD [(K、W)]パーティション分割:パーティショナ他)DEF参加

var rdd1 = sc.makeRDD(Array(("A","1"),("B","2"),("C","3")),2)
var rdd2 = sc.makeRDD(Array(("A","a"),("C","c"),("D","d")),2)
 
scala> rdd1.join(rdd2).collect
res10: Array[(String, (String, String))] = Array((A,(1,a)), (C,(3,c)))

関連のSQLと同等に参加する参加し、RDDリターンに応じて相関K上の唯一の2つの結果が間の関連付けのために、かもしれあなたはRDDの複数を関連付けたい場合は、2つだけRDDに参加し、複数の相関数回。

 

scala> val visit=sc.parallelize(List(("index.html","1.2.3.4"),("about.html","3,4,5,6"),("index.html","1.3.3.1"),("hello.html","1,2,3,4")),2)
visit: org.apache.spark.rdd.RDD[(String, String)] = ParallelCollectionRDD[3] at parallelize at <console>:24

scala> val page=sc.parallelize(List(("index.html","home"),("about.html","about"),("hi.html","2.3.3.3")),2);  
page: org.apache.spark.rdd.RDD[(String, String)] = ParallelCollectionRDD[4] at parallelize at <console>:24

scala> visit.join(page).collect
res10: Array[(String, (String, String))] = Array((about.html,(3,4,5,6,about)), (index.html,(1.2.3.4,home)), (index.html,(1.3.3.1,home)))

scala>  page.join(visit).collect
res11: Array[(String, (String, String))] = Array((about.html,(about,3,4,5,6)), (index.html,(home,1.2.3.4)), (index.html,(home,1.3.3.1)))

9 mapValue

 

DEF mapValues [U](F:(V)=> U):RDD [(K、U)]

同じマップにおける基本的なスイッチング動作は、マップ操作はV値で[V、K]の場合のみmapValuesあります。

scala> var rdd1 = sc.makeRDD(Array((1,"A"),(2,"B"),(3,"C"),(4,"D")),2)
rdd1: org.apache.spark.rdd.RDD[(Int, String)] = ParallelCollectionRDD[17] at makeRDD at <console>:24

scala> rdd1.mapValues(x => x + "_").collect
res14: Array[(Int, String)] = Array((1,A_), (2,B_), (3,C_), (4,D_))

ケース

 

scala> val key = sc.parallelize(List(("panda",0),("pink",3),("pirate",3),("panda",1),("pink",4)))
key: org.apache.spark.rdd.RDD[(String, Int)] = ParallelCollectionRDD[12] at parallelize at <console>:21

scala> key.collect
res15: Array[(String, Int)] = Array((panda,0), (pink,3), (pirate,3), (panda,1), (pink,4))

scala>key.mapValues(y=>(y,1)).collect
res16: Array[(String, (Int, Int))] = Array((panda,(0,1)), (pink,(3,1)), ((pirate,(3,1)), (panda,(1,1)), (pink,(4,1)))

 

10集計

 

小規模チョッパー

 

val rdd2_ = sc.parallelize(List("a","b","c","d","e","f"),2)

println( rdd2_.aggregate("")(_ + _, _ + _)) //defabc
println( rdd2_.aggregate("=")(_ + _, _ + _)) //==def=abc

2つのパーティションであるとして、パーティション番号=は、いくつかの意思決定を見えます

プロトタイプ:

def aggregate[U: ClassTag](zeroValue: U)(seqOp: (U, T) => U, combOp: (U, U) => U): U

公式文書の定義:

    Aggregate the elements of each partitions, 
and then the results for all the partitions, using given  combine 
functions and a neutral "zero value". This function can return a 
different result type, U, than the type of this RDD, T. Thus, we need 
one operation for merging a T into an U and one operation for merging 
two U's, as in scala. TraversableOnce. Both of these functions are 
allowed to modify and return their first argument instead of creating a 
new U to avoid memory allocation.

 

各パーティションについて得られた結果の所与の機能、およびゼロ値に組み合わせます。この関数は、異なるタイプ、Uはなく、RDDの種類、T.を返します したがって、我々は、2つのscala.TraversableOnceになるために合併オペレーティングUがあり、T Uに変身するためのアクションを必要としています。これらの機能の両方は、メモリの割り当てを回避するように、むしろ新しいUを作成するよりも、彼らの最初の引数の調整及び復帰を可能にします。

例1:

def seqOP(a:Int, b:Int):Int = {
    println("seqOp: " + a + "\t" +b )
    math.min(a,b)
}
//seqOP : (a:Int, b:Int)Int

def combOP(a:Int, b:Int):Int = {
    println("combOP: " + a + "\t" + b)
    a + b
}
//combOP:(a:Int,b:Int)Int

val z = sc.parallelize(List(1,2,3,4,5,6),2)
z.aggregate(3)(seqOP, combOP)
//output
seqOp:3     1  //partition 1:  seqOP(3,1)=>1
seqOp:3     4  //partition 2:seqOP(3,4)=>3
seqOp:1     2  //partition 1:seqOP(1,2)=>1
seqOp:3     5  //partition 2:seqOP(3,5)=>3
seqOp:1     3  //partition 1:seqOP(1,3)=>1
seqOp:3     6  //partition 2:seqOP(3,6)=>3
combOp:3    1 //combOP(3,1)=>4,3:zero value, 1:partiton 1's output
combOp:4    3  //combOP(4,3)=>7,3:partition2's output

//final output:7

例2:

val z = sc. parallelize ( List (1 ,2 ,3 ,4 ,5 ,6),3)
val zz = z. aggregate(3)(seqOP, combOp)
seqOp: 3    3
seqOp: 3    4
seqOp: 3    5
seqOp: 3    6
seqOp: 3    1
seqOp: 1    2

combOp: 3   3  //combOp(3:zero value,3:partition 1's output)=>6
combOp: 6   3  //combOp(6,3:partition 2's output)=>6
combOp: 9   1  //combOp(9,1:partition3's output)=>10
10

例3:

def seqOp(a:String, b:String) : String = {
println("seqOp: " + a + "\t" + b)
math.min(a.length , b.length ).toString
}
//seqOp: (a: String, b: String)String

def combOp(a:String, b:String) : String = {
println("combOp: " + a + "\t" + b)
a + b
}
//combOp: (a: String, b: String)String

val z = sc. parallelize ( List ("12" ,"23" ,"345" ,"4567") ,2)
z. aggregate ("")(seqOp, combOp)
seqOp:  345  //partition 1: ("","345")=>"0"
seqOp:  12  //partition 2:("","12")=>"0"
seqOp: 0    4567//partition 1:("0","4567")=>"1"
seqOp: 0    23 //partition 2:("0","23")=>"1"
combOp:     1 //combOp("","1")=>"1"
combOp: 1   1 //combOp("1","1")=>"11"
//r    es25: String = 11

注意:

1.reduce関数と関数(可換)可換組み合わせると結合(会合)しなければならない
定義された集約関数から2明らかなように、出力関数は、入力のタイプと同じタイプを組み合わせる必要があります。

Scalaの集約関数の2.Example

いくつかのASCIIアートが助けをしない場合を見てみましょう。の型シグネチャを考えてみましょう aggregate

def aggregate [B](z:B)(seqop:(B,A)=>B,combop:(B.B)=>B):B

the aggregate might work like this:
z   A   z   A   z   A   z   A
 \ /     \ /seqop\ /     \ /    
  B       B       B       B
    \   /  combop   \   /
      B _           _ B
         \ combop  /
              B


今私はGenSeq(「これ」、」ある」、」」、」例」)があり、私はそれでありますどのように多くの文字を知りたいです。私は、次のように記述することができます。

import scala.collection.GenSeq
val seq = GenSeq("This","is","an","example")
val chars = seq.aggregate(0)(_ + _.length, _ + _)

だから、最初のそれは、これを計算します:

0 + "This".length    //4
0 + "is".length      //2
0 + "an".length      //2
0 + "example".length //7

何それは次の缶(結果を組み合わせるの複数の方法がある)と予測されていませんが、それは(上記のアスキーアートのように)これを行う可能性があります。

4 + 2 // 6
2 + 7 // 9

これで、それはで終わり
6 + 9 // 15
、最終的な結果を与えます。さて、これはと構造が少し似ているfoldLeftが、それは追加の機能を有する(B,B)=>B倍はありません。この機能は、しかし、それは並行して作業することができます。

4つの計算の各初期計算が互いに独立しており、並列に行うことができること、例えば、考えます。彼らが依存している彼らの計算が終了しているが、これらの二つはまた、並列に実行することができたら、次の2(6と9になる)を開始することができます。

上記、並列化の。7 computitionsは、同じ時間AS AS 3リトルシリアル計算を取ることができる。
。計算上の7が3回に並列に計算することができます。

実際には、このような小さなコレクションを同期計算でのコストはどの利益を一掃するために十分な大きさになります。あなたがこれを折り畳んだ場合はさらに、それだけで合計4つの計算を取るだろう。あなたのコレクションが大きく得れば、しかし、あなたはいくつかの本当の利益を見始めます。

一方、考えてみましょうfoldLeftそれは、追加の機能を持っていないので、それはどんな計算を並列化することはできません。

(((0 + "This.length) + "is".length) + "an".length) + "example".length

外側の1を続行する前に、内側の括弧のそれぞれを計算する必要があります。

参考http://blog.csdn.net/power0405hf/article/details/50347005

 

 

 

公開された131元の記事 ウォン称賛79 ビュー310 000 +

おすすめ

転載: blog.csdn.net/qq_31780525/article/details/79111932