04、常用RDD操作整理
常用Transformation
注:某些函式只有PairRDD只有,而普通的RDD則沒有,比如gropuByKey、reduceByKey、sortByKey、join、cogroup等函式要根據Key進行分組或直接操作
RDD基本轉換: |
|||
RDD[U] map(f: T => U) T:原RDD中元素型別 U:新RDD中元素型別 |
函式將T元素轉換為新的U元素 |
rdd.map(x => x + 1) |
{1, 2, 3, 3} =>{2, 3, 4, 4} |
RDD[U] flatMap(f: T => TraversableOnce[U]) TraversableOnce:集合與迭代器的父類 |
函式將T元素轉換為含有新型別U元素的集合,並將這些集合展平(兩層轉換成一層)後的元素形成新的RDD |
rdd.flatMap(x => x.to(3)) |
{1, 2, 3, 3} =>{1, 2, 3, 2, 3, 3, 3} |
RDD[T] filter(f: T => Boolean) |
函式對每個元素進行過濾,通過的元素形成新的RDD |
rdd.filter(x => x != 1) |
{1, 2, 3, 3} =>{2, 3, 3} |
RDD[T] distinct() |
去重 |
rdd.distinct() |
{1, 2, 3, 3} =>{1, 2, 3} |
RDD[U] mapPartitions(f: Iterator[T] => Iterator[U]) |
與map一樣,只是轉換時是以分割槽為單位,將一個分割槽所有元素包裝成Iterator一次性傳入函式進行處理,而不像map函式那樣每個元素都會呼叫一個函式,即這裡有幾個分割槽則才呼叫幾次函式 假設有N個元素,有M個分割槽,那麼map的函式的將被呼叫N次,而mapPartitions被呼叫M次 |
valarr = Array(1, 2, 3, 4, 5) valrdd = sc.parallelize(arr, 2) rdd.mapPartitions((it: Iterator[Int]) => { var l = List[Int](); it.foreach((e: Int) => l = e * 2 :: l); l.iterator }) |
=>{2, 4, 6, 8, 10} |
RDD[U] mapPartitionsWithIndex(f: (Int, Iterator[T]) => Iterator[U]) |
與mapPartitions類似,不同的時函式多了個分割槽索引的引數 |
||
RDD[T] union(other: RDD[T]) |
兩個RDD 並集,包括重複的元素 |
rdd.union(otherRdd) |
{ 1, 2, 2, 3, 3} { 3, 4, 5} =>{1, 2, 2, 3, 3, 3, 4, 5} |
RDD[T] intersection(other: RDD[T]) |
兩個RDD 交集 |
rdd.intersection(otherRdd) |
{ 1, 2, 2, 3, 3} { 3, 4, 5} =>{3} |
RDD[T] subtract(other: RDD[T]) |
兩個RDD相減 |
rdd.subtract(otherRdd) |
{ 1, 2, 2, 3, 3} { 3, 4, 5} =>{1, 2, 2} |
RDD[(T, U)] cartesian(other: RDD[U]) |
兩個RDD相減笛卡兒積 |
rdd.cartesian(otherRdd) |
{ 1, 2 } { 3, 4} =>{(1,3),(1,4),(2,3),(2,4)} |
RDD[T] sortBy( f: (T) => K, ascending: Boolean,numPartitions: Int) |
根據轉換後的值進行排序,傳入的是一個(T) => K 轉換函式 |
rdd.sortBy(_._2, false, 1) 這裡根據value進行降序排序 |
{("leo", 65), ("tom", 50), ("marry", 100), ("jack", 80)} =>{("marry", 100),("jack", 80),("leo", 65), ("leo", 65)} |
RDD[Array[T]] glom() |
將RDD的每個分割槽中的型別為T的元素轉換換陣列Array[T] |
valarr = Array(1, 2, 3, 4, 5) valrdd = sc.parallelize(arr, 2) valarrRDD = rdd.glom()arrRDD.foreach { (arr: Array[Int]) => { println("[ " + arr.mkString(" ") + " ]"); } } =>[ 1 2 ],[ 3 4 5 ] |
|
鍵-值RDD轉換: |
|||
RDD[(K, U)] mapValues[U](f: V => U) K:key型別 V:value型別 |
將value轉換為新的U元素,Key不變 |
rdd.mapValues(_ + 1) |
{"class1", 80), ("class2", 70)} =>{"class1", 81), ("class2", 71)} |
RDD[(K, U)] flatMapValues(f: V => TraversableOnce[U]) |
對[K,V]型資料中的V值flatmap操作 |
rdd.flatMapValues(_.toCharArray()) |
{ (1, "ab"), (2, "bc")} =>{(1, 'a'), (1, 'b'), (2, 'b'), (2, 'c')} |
RDD[(K, Iterable[V])] groupByKey() |
根據key進行分組,同一組的元素組成Iterable<V>,並以(key, Iterable<V>)元組型別為元素作為新的RDD返回 |
rdd.groupByKey() |
{("class1", 80), ("class2", 75), ("class1", 90), ("class2", 60)} =>{("class1",[80,90]),("class2",[75,60])} |
RDD[(K, Iterable[T])] groupBy(f: T => K) T:原RDD元素型別 K:新RDD中元素Key的型別 |
根據函式將元素T對映成相應K後,以此K進行分組 |
rdd.groupBy({ case 1 => 1; case 2 => 2; case "二" => 2 }) |
{ 1, 2, "二" } =>{(1,[1]),(2,[2, "二"])} |
RDD[(K, V)] reduceByKey(func: (V, V) => V) |
先根據key進行分組,再對同一組中的的value進行reduce操作:第一次呼叫函式時傳入的是兩個Key所對應的value,從第二次往後,傳入的兩個引數中的第一個為上次函式計算的結果,第二個引數為其它Key的value |
rdd. reduceByKey(_ + _) |
{("class1", 80), ("class2", 75), ("class1", 90), ("class2", 60)} =>{("class1", 170),("class2", 135)} |
RDD[(K, V)] sortByKey() |
根據key的大小進行排序(注:並不是先以Key進行分組,再對組類進行排序,而是直接根據Key的值進行排序) |
rdd.sortByKey(false) |
{(65, "leo"), (50, "tom"),(100, "marry"), (85, "jack")} =>{(100, "marry"),(85, "jack"),(65, "eo"),(50, "tom")} |
RDD[(K, V)] foldByKey(zeroValue: V)(func: (V, V) => V): zeroValue:每個分割槽相同Key累計時的初始值,以及不同分割槽相同Key合併時的初始值 e.g., Nil for list concatenation, 0 for addition, or 1 for multiplication |
對每個value先進行func操作,且funcfoldByKey函式是通過呼叫函式實現的。 zeroVale:對V進行初始化,實際上是通過CombineByKey的createCombiner實現的 V => (zeroValue,V),再通過func函式對映成新的值,即func(zeroValue,V) func: Value將通過func函式按Key值進行合併(實際上是通過CombineByKey的mergeValue,mergeCombiners函式實現的,只不過在這裡,這兩個函式是相同的) |
valpeople = List(("Mobin", 1), ("Lucy", 2), ("Amy", 3), ("Amy", 4), ("Lucy", 5)) valrdd = sc.parallelize(people,2) valfoldByKeyRDD = rdd.foldByKey(10)((v1, v2) => { println(v1 + " + " + v2 + " = " + (v1 + v2)); v1 + v2 }) //先對每個V都加10,再對相同Key的value值相加 foldByKeyRDD.foreach(println) |
//處理第一個分割槽資料 10 + 1 = 11 // ("Mobin", 1) 10 + 2 = 12 // ("Lucy", 2) ===================== //處理第二個分割槽資料 10 + 3 = 13 // ("Amy", 3) 13 + 4 = 17 // ("Amy", 4)同分區同Key的Val先合併 10 + 5 = 15 // ("Lucy", 5) ===================== //將不同分割槽相同Key的Value合併起來 12 + 15 = 27 // "Lucy"跨分割槽,所以需合併 (Amy,17) (Mobin,11) (Lucy,27) |
RDD[(K, (V, Option[W]))] leftOuterJoin[W](other: RDD[(K, W)]): |
左外連線,包含左RDD的所有資料,如果右邊沒有與之匹配的用None表示 |
valarr = List(("A", 1), ("A", 2), ("B", 1)) valarr1 = List(("A", "A1"), ("A", "A2")) valrdd = sc.parallelize(arr, 2) valrdd1=sc.parallelize(arr1, 2) valleftOutJoinRDD = rdd.leftOuterJoin(rdd1) leftOutJoinRDD.foreach(println) |
=> (B,(1,None)) (A,(1,Some(A1))) (A,(1,Some(A2))) (A,(2,Some(A1))) (A,(2,Some(A2))) |
RDD[(K, (Option[V], W))] rightOuterJoin[W](other: RDD[(K, W)]) |
右外連線,包含右RDD的所有資料,如果左邊沒有與之匹配的用None表示 |
valarr = List(("A", 1), ("A", 2)) valarr1 = List(("A", "A1"), ("A", "A2"), ("B", 1)) valrdd = sc.parallelize(arr, 2) valrdd1 = sc.parallelize(arr1, 2) valleftOutJoinRDD = rdd.rightOuterJoin
常用Transformation
注:某些函式只有PairRDD只有,而普通的RDD則沒有,比如gropuByKey、reduceByKey、sortByKey、join、cogroup等函式要根據Key進行分組或直接操作
RDD基本轉換:
兩個 fas cpp pop 聲明 error: iterable ble 解釋 1、字典
1.1、為什麽有字典:
有個需求,存所有人的信息 這時候列表就不能輕易的表示完全names = [‘stone‘,‘liang‘]
1.2、元組:
定義符號()t = (1,2, 自動化運維工具 輸出信息 pat 秘鑰 img 系統命令 hair 作用 環境 今天心情不錯~~~~第25個生日了,又遇昨晚百年難得一見的藍月亮,所以昨晚連夜整理了文檔,會分為兩部分發出去,ansible批量化部署在工作中是非常實用,建議呢 整理大量常用模塊去練習1.1.1
概述要訪問一個變數的內容,可以直接使用其名稱。如果該變數是一個數組,可以使用變數名稱和關鍵字或索引的組合來訪問其內容。
像其他變數一樣,使用運算子=可以改變陣列元素的內容。陣列單元可以通過 array[key] 語法來訪問。
php定義函式:
<?php
$
Ubuntu操作基本快捷鍵
* 開啟主選單 = Alt + F1
* 執行 = Alt + F2
* 顯示桌面 = Ctrl + Alt + d
* 最小化當前視窗 = Alt + F9
* 最大化當前視窗 = Alt + F10
* 關閉當前視窗 ubuntu softwareGUI下的截屏軟件Shutter - 安裝步驟見(http://blog.csdn.net/hanshileiai/article/details/46843713)效率工具Indicator-stickynotes - 對標Win10上的Sticky Notes。安裝步驟見(h dir 命名 刪除 roo works suspend 備份目錄 xml文件 文件 KVM 虛擬機默認的配置文件在 /etc/libvirt/qemu 目錄下,默認是以虛擬機名稱命名的.xml文件,如下:
root@xuedianhu:~# ls /etc/libvirt MySQL用戶管理 MySQL用戶管理創建一個普通用戶並且授權1.grant all on *.* to 'user1' identified by 'passwd';grant all on *.* to 'user1' iden return AD eth ive ada encoding web ray lencod 一、常用Http操作
1.Get請求,有參數,無參數
2.Post 請求,有參數,無參數
3.文件簡單下載
/// <summary>
/// http 編輯模式 開發 .so 虛擬 64位 use roo 分頁 刪除文件 目錄
一、什麽是Linux
二、常用基礎指令
2.1、vi編輯
2.2、Linux文件類型
2.3、常用指令:增、刪、改、查、其他
三、Linux的目錄和權限
3.1、目錄
3
新增新使用者建議 GRANT 命令
一、grant 普通資料使用者,查詢、插入、更新、刪除 資料庫中所有表資料的權利。
grant select on testdb.* to [email protected]'%'
grant insert on testdb.* to [ema
hdfs shell的基本操作以及hdfsWeb檢視檔案
在安裝好hadoop叢集併成功的啟動了hdfs之後,我們就可以利用hdfs對檔案進行操作了,一下是對檔案的一些基本操作
特別注意:訪問HDFS目錄時,一定要帶有/ 否則命令會出錯!
hdfs基本操作
1、查詢命令 6. 資料雙向繫結
檢視和資料,只要一方發生變化,另一方跟著變化。
好處是不需要在程式碼中手動更新檢視,簡化開發,增加程式碼內聚性,程式碼可讀性更強。
缺點是當繫結的資料層次深、資料量大時,會影響效能。
雙向資料繫結的語法是[(x)].
修改article.component.html中的內容如下: 幾對幾的模型結構的使用場景為:一般根據業務需求,同一業務,需要向相關聯的多表插入刪除資料時,會用到。
一對一:
建立一個使用者表
class Users(models.Model):
username = models.CharField(max_length=20,null=true,blank 上面說了字串和整形,那現在要是想存一個班級的人的名字,這個班有200個人,怎麼存呢,用字串的話,那就是names = 'marry lily king .....'這樣,但是這樣存是可以存,那要是想取到某個人的名字怎麼取呢,不能再去裡面看一遍吧,那累死人了,為了解決這個問題,又有一種新的資料型別應運而生,那就 本文將演示按鈕控制元件的使用,按鈕是使用者介面中最常見的互動控制元件
在專案導航區,開啟檢視控制器的程式碼檔案【ViewController.swift】
1 import UIKit
2
3 class ViewController: UIViewController {
4 本文將演示標籤控制元件的換行功能,
在專案導航區,開啟檢視控制器的程式碼檔案【ViewController.swift】
1 import UIKit
2
3 class ViewController: UIViewController {
4
5 override f 本文將演示標籤控制元件的基礎用法,
在專案導航區,開啟檢視控制器的程式碼檔案【ViewController.swift】
1 import UIKit
2
3 class ViewController: UIViewController {
4
5 override f 本文將演示給標籤物件新增描邊效果,在專案資料夾上,點選滑鼠右鍵選單,
選擇【Create File】->【Cocoa Touch Class】->【Next】->
【Class】:MyLabel
【Subclass of 】:UILabel
【Language】:Swift
-&g 本文將演示開關控制元件的基本用法。
開關控制元件有兩個互斥的選項,它是用來開啟或關閉選項的控制元件。
在專案導航區,開啟檢視控制器的程式碼檔案【ViewController.swift】
1 import UIKit
2
3 class ViewController: UIViewCo |