Spark成長之路(13)-DataSet與DataFrame

來源:互聯網
上載者:User

Datasets and DataFrames

前言 源碼 DataFrame Dataset 建立dataset 讀取json串 RDD轉換為Dataset 總結 DataFrame 總結

前言

spark1.6中引入了DataSet和DataFrame的概念,然後Spark SQL的API也是基於這兩個概念的,到2.2推出的穩定版本的Structured Streaming也是依靠Spark SQL的API,到Spark MLib也開始由RDD的API轉換為DataFrame的API,這一步步的動作表示,未來的Spark根基是DataSet。所以也就引出了這篇文章,作者意圖把DataSet認真的瞭解一下。 源碼

我們先來看看這兩個對象的源碼。 DataFrame

package object sql {  ...  type DataFrame = Dataset[Row]}

可以看出DataFrame是Dataset的特例,所以我先瞭解Dataset這個介面。 Dataset

private[sql] object Dataset {  def apply[T: Encoder](sparkSession: SparkSession, logicalPlan: LogicalPlan): Dataset[T] = {    new Dataset(sparkSession, logicalPlan, implicitly[Encoder[T]])  }  def ofRows(sparkSession: SparkSession, logicalPlan: LogicalPlan): DataFrame = {    val qe = sparkSession.sessionState.executePlan(logicalPlan)    qe.assertAnalyzed()    new Dataset[Row](sparkSession, qe, RowEncoder(qe.analyzed.schema))  }}class Dataset[T] private[sql](    @transient val sparkSession: SparkSession,    @DeveloperApi @InterfaceStability.Unstable @transient val queryExecution: QueryExecution,    encoder: Encoder[T])  extends Serializable {

Dataset類似於RDD,但是,不同於RDD的是,Dataset有特殊的編碼器去序列化Jvm對象以及網路資料,開發過spark程式的都知道,之前RDD一般會使用kryo或者java序列化器來做這些工作。序列化是把對象序列化成二進位,Dataset可以直接操作位元據,進行相關的轉換操作,這比RDD要強大。
因為Dataset是強型別資料集,使用時必須說明資料類型。 建立dataset

case class Person(name: String, age: Int)  def main(args: Array[String]): Unit = {    import spark.implicits._    val caseClassDF = Seq(Person("Andy", 32)).toDS    caseClassDF.show()  }

上面代碼會自動把資料對應為一張表,表的列名分別是name和age。我們來看一下執行結果:

+----+---+|name|age|+----+---+|Andy| 32|+----+---+

可以看出來,sparksession自動將一個Person對象作為表中一條資料。

如果我們不用Person封裝呢,代碼修改成如下:

> val caseClassDF = Seq("Andy", "doctorq").toDS+-------+|  value|+-------+|   Andy||doctorq|+-------+

預設給出一個列名”value”,每一條資料當成一個記錄。如果一行資料有多個屬性,還是用對象封裝一下比較方便。 讀取json串

val path = "src/main/resources/people.json"    val peopleDS = spark.read.json(path).as[Person]    peopleDS.show()

SparkSession提供的讀取外部檔案的介面非常的簡單。 RDD轉換為Dataset

val peopleDF = spark.sparkContext      .textFile("src/main/resources/people.txt")      .map(_.split(","))      .map(attributes => Person(attributes(0), attributes(1).trim.toInt))      .toDS()
總結

得到DataSet對象的方式有很多,普通的集合,讀取外部資料,都可以很方便的轉換為DS,但是要記得引入隱式轉換。import spark.implicits._,但是有一點就是需要指定類型。 DataFrame

DataFrame為Dataset類型為Row對象,我們來看一下Row對象:

定義了行中的元素個數,資料類型schema,用來定義屬性類型。這個Row也類似一個集合類型,裡面定義了集合的大小,以及每個元素的類型,還定義了一些擷取某個位置的值。

我們在之前說Dataset之前,都說了建立Dataset都要指定資料類型,而DataFrame是特殊的,只需要用Row太泛指,其他交給Row來處理,這就把一些無法定義對象的,用DF來代替了。 總結

Dataset作為新版本的spark基礎資料集,未來還將逐漸替代RDD,正式成為底層支援,目前的流式計算和機器學習庫的轉移,都是這方面的訊號。之前看文章說Dataset是繼承RDD的,但實際上是獨立存在的,不過可以由RDD轉換而來。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.