web-dev-qa-db-ja.com

SparkのDataFrame、Dataset、およびRDDの違い

Apache SparkでRDDDataFrame(Spark 2.0.0 DataFrameはDataset[Row]の単なる型エイリアスです)の違いは何だろうか。

一方を他方に変換できますか?

206
menorah84

DataFrameは、 "DataFrame定義"のグーグル検索でうまく定義されています。

データフレームはテーブル、つまり2次元配列のような構造で、各列に1つの変数の測定値が含まれ、各行に1つのケースが含まれます。

そのため、DataFrameには、その表形式のために追加のメタデータがあります。これにより、Sparkは最終的なクエリに対して特定の最適化を実行できます。

一方、RDDは単にResilientDが割り当てられたものですDatasetは、それに対して実行できる操作ほど最適化できないブラックボックスのデータであり、それほど制約がありません。

ただし、RDDメソッドを使用してDataFrameからrddに移動することも、RDDメソッドを使用してDataFrameからtoDFに移動することもできます(RDDが表形式の場合)。

一般的なクエリの最適化が組み込まれているため、可能な場合はDataFrameを使用することをお勧めします。

197
Justin Pihony

まずDataFrameSchemaRDDから進化したことです。

depreated method toSchemaRDD

はい。DataframeRDDの間の変換は絶対に可能です。

以下はサンプルコードの一部です。

  • df.rddRDD[Row]です

以下はデータフレームを作成するためのオプションのいくつかです。

  • 1)yourrddOffrow.toDFDataFrameに変換されます。

  • 2)SQLコンテキストのcreateDataFrameを使う

    val df = spark.createDataFrame(rddOfRow, schema)

スキーマは以下のオプションのうちのいくつかから得ることができます Nice SO post ..で説明されているように
スカラ格クラスとスカラ反映apiより

import org.Apache.spark.sql.catalyst.ScalaReflection
val schema = ScalaReflection.schemaFor[YourScalacaseClass].dataType.asInstanceOf[StructType]

またはEncodersを使用して

import org.Apache.spark.sql.Encoders
val mySchema = Encoders.product[MyCaseClass].schema

schemaで説明されているように、StructTypeStructFieldを使って作成することもできます。

val schema = new StructType()
  .add(StructField("id", StringType, true))
  .add(StructField("col1", DoubleType, true))
  .add(StructField("col2", DoubleType, true)) etc...

image description

実際には3つのApache Spark APIがあります。

enter image description here

  1. RDD API:

RDD(Resilient Distributed Dataset)APIは1.0リリース以来Sparkにあります。

RDD APIは、データに対して計算を実行するためのmap()、filter()、およびreduce()などの多くの変換メソッドを提供します。これらの各メソッドは変換されたデータを表す新しいRDDをもたらします。ただし、これらのメソッドは実行する操作を定義しているだけであり、変換はアクションメソッドが呼び出されるまで実行されません。アクションメソッドの例はcollect()とsaveAsObjectFile()です。

RDDの例:

rdd.filter(_.age > 21) // transformation
   .map(_.last)// transformation
.saveAsObjectFile("under21.bin") // action

例:RDDを使用した属性によるフィルター処理

rdd.filter(_.age > 21)
  1. DataFrame API

Spark 1.3は、Project Tungstenイニシアチブの一環として、新しいDataFrame APIを導入しました。これは、Sparkのパフォーマンスとスケーラビリティの向上を目指しています。 DataFrame APIは、データを記述するためのスキーマの概念を導入し、Sparkがスキーマを管理し、ノード間でのみデータを渡すことを可能にします。これは、Javaシリアライゼーションを使うよりもはるかに効率的です。

DataFrame APIは、SparkのCatalystオプティマイザが実行できるリレーショナルクエリプランを構築するためのAPIであるため、RDD APIとは根本的に異なります。 APIは、クエリプランの構築に精通している開発者にとって自然なものです。

SQLスタイルの例:

df.filter("age > 21");

制限事項:コードは名前でデータ属性を参照しているため、コンパイラがエラーを検出することはできません。属性名が正しくない場合は、クエリプランが作成されたときにエラーが実行時にのみ検出されます。

DataFrame APIのもう1つの欠点は、非常にスケーラ中心であり、Javaをサポートしていますが、サポートが制限されていることです。

たとえば、既存のDataFrameのJavaオブジェクトからRDDを作成する場合、SparkのCatalystオプティマイザはスキーマを推測できず、DataFrame内のすべてのオブジェクトがscala.Productインターフェースを実装すると想定します。 Scalaのcase classは、このインターフェースを実装しているので、うまくいきます。

  1. Dataset API

Spark 1.6でAPIプレビューとしてリリースされたDataset APIは、両方の長所を提供することを目的としています。 RDD APIの使い慣れたオブジェクト指向プログラミングスタイルとコンパイル時の型安全性。ただし、Catalystクエリーオプティマイザのパフォーマンス上の利点があります。データセットはDataFrame APIと同じ効率的なオフヒープストレージメカニズムも使用します。

データのシリアル化に関しては、Dataset APIにはエンコーダという概念があり、これはJVM表現(オブジェクト)とSparkの内部バイナリフォーマットとの間の変換を行います。 Sparkには、オフヒープデータとやり取りするためのバイトコードを生成し、オブジェクト全体のシリアル化を解除することなく個々の属性へのオンデマンドアクセスを提供するという点で非常に高度な組み込みエンコーダがあります。 Sparkはまだカスタムエンコーダを実装するためのAPIを提供していませんが、それは将来のリリースで計画されています。

さらに、Dataset APIは、JavaとScalaの両方で同等に機能するように設計されています。 Javaオブジェクトを扱うときは、完全にBeanに準拠していることが重要です。

Dataset API SQLスタイル:

dataset.filter(_.age < 21);

評価差分。 DataFrameDataSetの間:enter image description here

詳しく読む...データブリック 記事

182
Ram Ghadiyaram

Apache Sparkは3種類のAPIを提供します

  1. RDD
  2. DataFrame
  3. データセット

Comparing RDD, Dataframe and Dataset APIs

これは、RDD、Dataframe、およびDataset間のAPI比較です。

RDD

Sparkが提供する主な抽象概念は、分散型データセット(RDD)です。これは、クラスタのノード間でパーティション化された要素を集めたもので、並行して操作できます。

RDDの特徴: -

  • 分散収集:
    RDDはMapReduce操作を使用します。これは、クラスター上の並列分散アルゴリズムで大規模データセットを処理および生成するために広く採用されています。これにより、ユーザーは作業の分散やフォールトトレランスについて心配することなく、一連の高レベル演算子を使用して並列計算を作成できます。

  • 不変:分割されたレコードの集合で構成されるRDD。パーティションはRDDの並列処理の基本単位で、各パーティションは不変で既存パーティションの変換によって作成された1つの論理的なデータ分割です。可変性は計算の一貫性を保つのに役立ちます。

  • フォールトトレラント:RDDの一部のパーティションを失った場合は、複数のノード間でデータ複製を行うのではなく、そのパーティションで変換を系統別に実行して同じ計算を実行できます。この特性はRDDの最大の利点です。データ管理と複製における多くの手間が省かれ、高速計算が達成されるからです。

  • 遅延評価:Sparkのすべての変換は遅延しています。つまり、結果はすぐには計算されません。代わりに、彼らはただいくつかの基本データセットに適用された変換を覚えています。変換は、アクションが結果をドライバプログラムに返す必要がある場合にのみ計算されます。

  • 関数変換:RDDは、既存のデータセットから新しいデータセットを作成する変換と、実行後にドライバプログラムに値を返すアクションという2種類の操作をサポートします。データセット.

  • データ処理形式:
    構造化されたデータと非構造化データを簡単かつ効率的に処理できます。

  • サポートされているプログラミング言語:
    RDD APIは、Java、Scala、Python、およびRで使用可能です。

RDDの制限: -

  • 内蔵の最適化エンジンはありません。構造化データを扱う場合、RDDは触媒オプティマイザやTungsten実行エンジンを含むSparkの高度なオプティマイザを利用することはできません。開発者はそれぞれのRDDをその属性に基づいて最適化する必要があります。

  • 構造化データの処理:データフレームやデータセットとは異なり、RDDは取り込まれたデータのスキーマを推測せず、ユーザーに指定を要求します。

データフレーム

SparkはSpark 1.3リリースでデータフレームを導入しました。データフレームは、RDDが抱えていた主な課題を克服します。

DataFrameは、名前付き列に編成されたデータの分散コレクションです。概念的には、リレーショナルデータベースまたはR/Pythonデータフレーム内のテーブルと同等です。 Dataframeと一緒に、Sparkは触媒オプティマイザも導入しました。これは高度なプログラミング機能を利用して拡張可能なクエリオプティマイザを構築するものです。

データフレームの特徴: -

  • 行オブジェクトの分散コレクション:DataFrameは、名前付き列に編成されたデータの分散コレクションです。概念的にはリレーショナルデータベースのテーブルと同等ですが、内部ではより高度な最適化が行われています。

  • データ処理:構造化および非構造化データフォーマット(Avro、CSV、Elastic Search、Cassandra)およびストレージシステム(HDFS、Hiveテーブル、MySQLなど)の処理。それはこれらすべての様々なデータソースから読み書きすることができます。

  • 触媒最適化プログラムを使用した最適化:SQL照会とDataFrame APIの両方を強化します。データフレームは、4段階で触媒ツリー変換フレームワークを使用します。

    1.Analyzing a logical plan to resolve references
    2.Logical plan optimization
    3.Physical planning
    4.Code generation to compile parts of the query to Java bytecode.
    
  • Hiveの互換性:Spark SQLを使用すると、既存のHiveウェアハウスで未修正のHiveクエリを実行できます。 HiveフロントエンドとMetaStoreを再利用し、既存のHiveデータ、クエリ、およびUDFとの完全な互換性を提供します。

  • Tungsten:Tungstenは物理的な実行バックエンドを提供し、メモリを明示的に管理し、式評価用のバイトコードを動的に生成します。

  • サポートされているプログラミング言語:
    データフレームAPIは、Java、Scala、Python、およびRで利用可能です。

データフレームの制限: -

  • コンパイル時型の安全性:説明したように、Dataframe APIは、構造がわからないときにデータを操作することを制限するコンパイル時の安全性をサポートしません。次の例はコンパイル時に機能します。ただし、このコードを実行するとランタイム例外が発生します。

例:

case class Person(name : String , age : Int) 
val dataframe = sqlContext.read.json("people.json") 
dataframe.filter("salary > 10000").show 
=> throws Exception : cannot resolve 'salary' given input age , name

これは、いくつかの変換および集約ステップを使用しているときには特に困難です。

  • ドメインオブジェクト(失われたドメインオブジェクト)を操作することはできません。ドメインオブジェクトをデータフレームに変換した後は、それを再生成することはできません。次の例では、personRDDからpersonDFを作成したら、Personクラスの元のRDD(RDD [Person])を元に戻すことはできません。

例:

case class Person(name : String , age : Int)
val personRDD = sc.makeRDD(Seq(Person("A",10),Person("B",20)))
val personDF = sqlContext.createDataframe(personRDD)
personDF.rdd // returns RDD[Row] , does not returns RDD[Person]

データセットAPI

データセットAPIは、タイプセーフなオブジェクト指向プログラミングインタフェースを提供するDataFramesの拡張です。これは、リレーショナルスキーマにマップされる、強く型付けされた不変のオブジェクトのコレクションです。

データセットの中核をなすAPIは、エンコーダと呼ばれる新しい概念で、JVMオブジェクトと表形式の間の変換を担当します。表形式の表現は、Sparkの内部タングステンバイナリフォーマットを使用して保存され、シリアル化されたデータに対する操作とメモリ使用率の向上を可能にします。 Spark 1.6は、プリミティブ型(String、Integer、Longなど)、Scalaケースクラス、Java Beansなど、さまざまな型のエンコーダーの自動生成をサポートしています。

データセットの特徴: -

  • RDDとデータフレームの両方の長所を提供します。RDD(関数型プログラミング、タイプセーフ)、DataFrame(リレーショナルモデル、クエリ最適化、タングステン実行、ソート、シャッフル)

  • エンコーダ:エンコーダを使用すると、任意のJVMオブジェクトをデータセットに簡単に変換でき、ユーザーはDataframeとは異なり、構造化データと非構造化データの両方を扱うことができます。

  • サポートされるプログラミング言語:データセットAPIは現在ScalaとJavaでのみ利用可能です。 PythonとRは、現在バージョン1.6ではサポートされていません。 Pythonのサポートはバージョン2.0を予定しています。

  • 型安全性:データセットAPIは、データフレームでは利用できなかったコンパイル時の安全性を提供します。以下の例では、データセットがラムダ関数をコンパイルしてドメインオブジェクトを操作する方法を見ることができます。

例:

case class Person(name : String , age : Int)
val personRDD = sc.makeRDD(Seq(Person("A",10),Person("B",20)))
val personDF = sqlContext.createDataframe(personRDD)
val ds:Dataset[Person] = personDF.as[Person]
ds.filter(p => p.age > 25)
ds.filter(p => p.salary > 25)
 // error : value salary is not a member of person
ds.rdd // returns RDD[Person]
  • 相互運用性:データセットを使用すると、ボイラープレートコードを使用せずに、既存のRDDとデータフレームを簡単にデータセットに変換できます。

データセットAPIの制限: -

  • Stringへの型キャストが必要です。データセットからデータを照会するには、現在クラス内のフィールドを文字列として指定する必要があります。データを照会すると、列を必要なデータ型にキャストする必要があります。一方、データセットに対してマップ操作を使用すると、Catalystオプティマイザは使用されません。

例:

ds.select(col("name").as[String], $"age".as[Int]).collect()

PythonとRはサポートされていません。リリース1.6以降、データセットはScalaとJavaのみをサポートします。 PythonサポートはSpark 2.0で導入される予定です。

Datasets APIは、優れた型安全性と関数型プログラミングにより、既存のRDDおよびDataframe APIよりも優れた点がいくつかあります。APIの型キャスト要件に挑戦しても、必要な型安全性が損なわれ、コードが壊れやすくなります。

119
Amit Dubey

RDD

Sparkが提供する主な抽象概念は、分散型データセット(RDD)です。これは、クラスタのノード間でパーティション化された要素を集めたもので、並行して操作できます。

RDDの特徴: -

  • 分散コレクション:
    RDDはMapReduce操作を使用します。これは、クラスター上の並列分散アルゴリズムで大規模データセットを処理および生成するために広く採用されています。これにより、ユーザーは作業の分散やフォールトトレランスについて心配することなく、一連の高レベル演算子を使用して並列計算を作成できます。

  • 不変:分割されたレコードの集合で構成されるRDD。パーティションはRDDの並列処理の基本単位で、各パーティションは不変で既存パーティションの変換によって作成された1つの論理的なデータ分割です。可変性は計算の一貫性を保つのに役立ちます。

  • フォールトトレラント:RDDの分割を失った場合は、その分割での変換を系統で再生して同じ計算を実行するのではなく、複数のノードにまたがってデータ複製を行う。この特徴は、データ管理と複製における多くの労力を節約し、したがってより高速な計算を達成するので、RDDの最大の利点です。

  • 遅延評価:Sparkのすべての変換はすぐに結果を計算しないという点で遅延します。代わりに、彼らはただいくつかの基本データセットに適用された変換を覚えています。変換は、アクションが結果をドライバプログラムに返す必要がある場合にのみ計算されます。

  • 関数変換:RDDは、既存のものから新しいデータセットを作成する変換と、ドライバに値を返すアクションの2種類の操作をサポートします。データセットで計算を実行した後にプログラムします。

  • データ処理形式:

非構造化データと同様に構造化されたデータも簡単かつ効率的に処理できます。

  • サポートされているプログラミング言語:
    RDD APIは、Java、Scala、Python、およびRで使用可能です。

RDDの制限: -

  • 内蔵の最適化エンジンはありません。構造化データを扱う場合、RDDは、触媒オプティマイザやTungsten実行エンジンなどのSparkの高度なオプティマイザを利用することはできません。開発者はそれぞれのRDDをその属性に基づいて最適化する必要があります。

  • 構造化データの処理:データフレームやデータセットとは異なり、RDDは取り込まれたデータのスキーマを推測せず、ユーザーに指定を要求します。

データフレーム

SparkはSpark 1.3リリースでデータフレームを導入しました。データフレームは、RDDが抱えていた主な課題を克服します。

DataFrameは、名前付き列に編成されたデータの分散コレクションです。概念的には、リレーショナルデータベースまたはR/Pythonデータフレーム内のテーブルと同等です。 Dataframeと一緒に、Sparkは触媒オプティマイザも導入しました。これは高度なプログラミング機能を利用して拡張可能なクエリオプティマイザを構築するものです。

データフレームの特徴: -

  • 行オブジェクトの分散コレクション:DataFrameは、名前付き列に編成されたデータの分散コレクションです。概念的にはリレーショナルデータベースのテーブルと同等ですが、内部ではより高度な最適化が行われています。

  • データ処理:構造化および非構造化データフォーマット(Avro、CSV、Elastic Search、およびCassandra)およびストレージシステム(HDFS、Hiveテーブル、MySQLなど)の処理)それはこれらすべての様々なデータソースから読み書きすることができます。

  • 触媒最適化プログラムを使用した最適化:SQLクエリとDataFrame APIの両方を強化します。データフレームは、4段階で触媒ツリー変換フレームワークを使用します。

    1.Analyzing a logical plan to resolve references
    2.Logical plan optimization
    3.Physical planning
    4.Code generation to compile parts of the query to Java bytecode.
    
  • Hiveの互換性:Spark SQLを使用すると、既存のHiveウェアハウスで未修正のHiveクエリを実行できます。 HiveフロントエンドとMetaStoreを再利用し、既存のHiveデータ、クエリ、およびUDFとの完全な互換性を提供します。

  • Tungsten:Tungstenは物理的な実行バックエンドを提供し、メモリを明示的に管理し、式評価用のバイトコードを動的に生成します。

  • サポートされているプログラミング言語:
    データフレームAPIは、Java、Scala、Python、およびRで利用可能です。

データフレームの制限: -

  • コンパイル時の型の安全性:説明したように、Dataframe APIはコンパイル時の安全性をサポートしていないため、構造がわからないときのデータ操作は制限されます。次の例はコンパイル時に機能します。ただし、このコードを実行するとランタイム例外が発生します。

例:

case class Person(name : String , age : Int) 
val dataframe = sqlContect.read.json("people.json") 
dataframe.filter("salary > 10000").show 
=> throws Exception : cannot resolve 'salary' given input age , name

これは、いくつかの変換および集約ステップを使用しているときには特に困難です。

  • ドメインオブジェクト(失われたドメインオブジェクト)を操作することはできません。ドメインオブジェクトをデータフレームに変換すると、それを再生成することはできません。次の例では、personRDDからpersonDFを作成したら、Personクラスの元のRDD(RDD [Person])を元に戻すことはできません。

例:

case class Person(name : String , age : Int)
val personRDD = sc.makeRDD(Seq(Person("A",10),Person("B",20)))
val personDF = sqlContect.createDataframe(personRDD)
personDF.rdd // returns RDD[Row] , does not returns RDD[Person]

データセットAPI

データセットAPIは、タイプセーフなオブジェクト指向プログラミングインタフェースを提供するDataFramesの拡張です。これは、リレーショナルスキーマにマップされる、強く型付けされた不変のオブジェクトのコレクションです。

データセットの中核をなすAPIは、エンコーダと呼ばれる新しい概念で、JVMオブジェクトと表形式の間の変換を担当します。表形式の表現は、Sparkの内部タングステンバイナリフォーマットを使用して保存され、シリアル化されたデータに対する操作とメモリ使用率の向上を可能にします。 Spark 1.6は、プリミティブ型(String、Integer、Longなど)、Scalaケースクラス、Java Beansなど、さまざまな型のエンコーダーの自動生成をサポートしています。

データセットの特徴: -

  • RDDとデータフレームの両方の長所を提供します。RDD(関数型プログラミング、タイプセーフ)、DataFrame(リレーショナルモデル、クエリ最適化、タングステン実行、ソート、シャッフル)

  • エンコーダ:エンコーダを使用すると、任意のJVMオブジェクトをデータセットに変換するのが簡単になり、データフレームとは異なり、構造化データと非構造化データの両方を扱うことができます。 。

  • サポートされるプログラミング言語:データセットAPIは現在ScalaとJavaでのみ利用可能です。 PythonとRは、現在バージョン1.6ではサポートされていません。 Pythonのサポートはバージョン2.0を予定しています。

  • 型安全性:データセットAPIは、データフレームでは利用できなかったコンパイル時の安全性を提供します。以下の例では、データセットがラムダ関数をコンパイルしてドメインオブジェクトを操作する方法を見ることができます。

例:

case class Person(name : String , age : Int)
val personRDD = sc.makeRDD(Seq(Person("A",10),Person("B",20)))
val personDF = sqlContect.createDataframe(personRDD)
val ds:Dataset[Person] = personDF.as[Person]
ds.filter(p => p.age > 25)
ds.filter(p => p.salary > 25)
 // error : value salary is not a member of person
ds.rdd // returns RDD[Person]
  • 相互運用性:データセットを使用すると、ボイラープレートコードなしで既存のRDDとデータフレームを簡単にデータセットに変換できます。

データセットAPIの制限: -

  • Stringへの型キャストが必要です。現在、データセットからデータを照会するには、クラス内のフィールドを文字列として指定する必要があります。データを照会すると、列を必要なデータ型にキャストする必要があります。一方、データセットに対してマップ操作を使用すると、Catalystオプティマイザは使用されません。

例:

ds.select(col("name").as[String], $"age".as[Int]).collect()

PythonとRはサポートされていません。リリース1.6以降、データセットはScalaとJavaのみをサポートします。 PythonサポートはSpark 2.0で導入される予定です。

Datasets APIは、優れた型安全性と関数型プログラミングにより、既存のRDDおよびDataframe APIよりも優れた点がいくつかあります。APIの型キャスト要件に挑戦しても、必要な型安全性が損なわれ、コードが壊れやすくなります。

59
Amit Dubey

1つの画像内のすべて(RDD、DataFrame、およびDataSet)。

RDD vs DataFrame vs DataSet

画像のクレジット

RDD

RDDは、並列で操作できる要素のフォールトトレラントなコレクションです。

DataFrame

DataFrameは、名前付き列に編成されたデータセットです。概念的には、リレーショナルデータベースのテーブルまたはR/Pythonのデータフレームに相当しますただし、ボンネットの下のより最適化が進んでいます

Dataset

Datasetは、分散データコレクションです。データセットは、Spark 1.6で追加された新しいインターフェイスで、RDDの利点(強力なタイピング、強力なラムダ関数を使用する機能)をSparkの利点SQLの最適化された実行エンジン


注:

行のデータセットDataset[Row])は、Scala/Javaでしばしばas DataFramesを参照します。


Nice comparison of all of them with a code snippet.

RDD vs DataFrame vs DataSet with code

ソース


Q:RDDからDataFrame、またはその逆のように、一方を他方に変換できますか?

はい、両方可能です

1。 RDDからDataFrameへの.toDF()

val rowsRdd: RDD[Row] = sc.parallelize(
  Seq(
    Row("first", 2.0, 7.0),
    Row("second", 3.5, 2.5),
    Row("third", 7.0, 5.9)
  )
)

val df = spark.createDataFrame(rowsRdd).toDF("id", "val1", "val2")

df.show()
+------+----+----+
|    id|val1|val2|
+------+----+----+
| first| 2.0| 7.0|
|second| 3.5| 2.5|
| third| 7.0| 5.9|
+------+----+----+

他の方法: RDDオブジェクトをSparkのデータフレームに変換する

2。 DataFrame/DataSetからRDDへの.rdd() method

val rowsRdd: RDD[Row] = df.rdd() // DataFrame to RDD
36
mrsrinivas

単にRDDはコアコンポーネントですが、DataFrameはspark 1.30で導入されたAPIです。

RDD

RDDと呼ばれるデータパーティションのコレクション。これらのRDDは、次のようないくつかのプロパティに従う必要があります。

  • 不変、
  • 耐障害性、
  • 分配された、
  • もっと。

ここでRDDは構造化または非構造化のどちらかです。

データフレーム

DataFrameはScala、Java、PythonおよびRで利用可能なAPIです。それはあらゆるタイプの構造化データおよび半構造化データを処理することを可能にします。 DataFrameを定義するために、DataFrameという名前の列に編成された分散データのコレクション。 RDDsDataFrameを簡単に最適化できます。 DataFrameを使用すると、JSONデータ、寄木細工データ、HiveQLデータを一度に処理できます。

val sampleRDD = sqlContext.jsonFile("hdfs://localhost:9000/jsondata.json")

val sample_DF = sampleRDD.toDF()

ここでSample_DFはDataFrameと見なします。 sampleRDDは(生データ)RDDと呼ばれます。

24
Venu A Positive

DataFrameは弱い型付けであり、開発者は型システムの恩恵を受けていません。たとえば、SQLから何かを読み、それに対して何らかの集計を実行したいとしましょう。

val people = sqlContext.read.parquet("...")
val department = sqlContext.read.parquet("...")

people.filter("age > 30")
  .join(department, people("deptId") === department("id"))
  .groupBy(department("name"), "gender")
  .agg(avg(people("salary")), max(people("age")))

people("deptId")と言っても、IntLongは戻ってきません。操作する必要のあるColumnオブジェクトが戻ってきます。 Scalaのような豊富な型システムを持つ言語では、コンパイル時に発見される可能性があるものに対する実行時エラーの数を増やすすべての型安全性を失うことになります。

それどころか、DataSet[T]は型付けされています。あなたがするとき:

val people: People = val people = sqlContext.read.parquet("...").as[People]

実際にはPeopleオブジェクトが返されています。ここでdeptIdは実際の整数型で列型ではないため、型システムを利用しています。

Spark 2.0から、DataFrameとDataSet APIは統合されます。ここで、DataFrameDataSet[Row]の型エイリアスになります。

23
Yuval Itzchakov

答えのほとんどは正しいですここで1点を追加したいだけです

Spark 2.0では、2つのAPI(DataFrame + DataSet)は単一のAPIに統合されます。

「DataFrameとDatasetの統一:ScalaとJavaでは、DataFrameとDatasetは統一されています。つまり、DataFrameは単なるRowのDatasetの型エイリアスです。PythonとRでは、型安全性が欠如しているので

データセットはRDDに似ていますが、Javaシリアル化やKryoを使用する代わりに、特殊なエンコーダを使用してオブジェクトを処理したりネットワーク経由で送信したりします。

Spark SQLは既存のRDDをデータセットに変換するための2つの異なる方法をサポートします。最初の方法では、リフレクションを使用して、特定の種類のオブジェクトを含むRDDのスキーマを推測します。このリフレクションベースのアプローチは、より簡潔なコードにつながり、Sparkアプリケーションを書いている間にすでにスキーマを知っている場合にはうまく機能します。

データセットを作成する2つ目の方法は、スキーマを構築してそれを既存のRDDに適用することを可能にするプログラムインターフェースを使用することです。このメソッドはより冗長ですが、実行時まで列とその型がわからないときにデータセットを作成できます。

ここであなたはデータフレーム会話の答えのRDDを見つけることができます

スパークでrddオブジェクトをデータフレームに変換する方法

9
vaquar khan

DataFrameはRDBMSのテーブルと同等であり、RDDの「ネイティブ」分散コレクションと同様の方法で操作することもできます。 RDDとは異なり、Dataframeはスキーマを追跡し、より最適化された実行につながるさまざまなリレーショナル操作をサポートします。各DataFrameオブジェクトは論理的な計画を表しますが、その「怠惰な」性質のため、ユーザーが特定の「出力操作」を呼び出すまで実行は行われません。

7
Silver Blaze

使用法の観点からの洞察、RDD対DataFrameはほとんどありません。

  1. RDDは素晴らしいです。それらが私たちにほとんどあらゆる種類のデータを扱うためのすべての柔軟性を私たちに与えるので。非構造化データ、半構造化データ、構造化データ。多くの場合、データはDataFrameに適合する準備ができていないため(JSONでも)、RDDを使用してデータをデータフレームに収まるように前処理することができます。 RDDはSparkのコアデータ抽象化です。
  2. RDDで可能なすべての変換がDataFrameで可能というわけではありません。例えば、subtract()はRDD vsに対するもので、except()はDataFrameに対するものです。
  3. DataFrameはリレーショナルテーブルのようなものであるため、set/relational theory変換を使用する場合は厳密な規則に従います。たとえば、2つのデータフレームを結合する場合は、両方のDFSが同じ列数と関連列データ型を持つ必要があります。列名は異なる場合があります。これらの規則はRDDには適用されません。 これはこれらの事実を説明する良いチュートリアル です。
  4. 他の人がすでに詳しく説明したように、DataFrameを使用するとパフォーマンスが向上します。
  5. DataFrameを使用すると、RDDでプログラミングするときのように任意の関数を渡す必要がなくなります。
  6. データフレームをスパークエコシステムのSparkSQL領域にあるようにプログラムするにはSQLContext/HiveContextが必要ですが、RDDにはSpark CoreライブラリにあるSparkContext/JavaSparkContextのみが必要です。
  7. スキーマを定義できれば、RDDからdfを作成できます。
  8. Dfをrddに、rddをdfに変換することもできます。

私はそれが役立つことを願っています!

4
skvyas

Dataframeは、それぞれがレコードを表すRowオブジェクトのRDDです。データフレームはその行のスキーマ(すなわちデータフィールド)も知っている。データフレームは通常のRDDのように見えますが、内部的にはスキーマを利用してデータをより効率的に格納します。さらに、SQLクエリを実行する機能など、RDDでは利用できない新しい操作を提供します。データフレームは、外部データソース、クエリの結果、または通常のRDDから作成できます。

参考文献:Zaharia M.他ラーニングスパーク(O'Reilly、2015)

4
Neethu

Spark RDD (resilient distributed dataset)

RDDはコアデータ抽象化APIであり、Spark(Spark 1.0)の最初のリリース以降に利用可能です。分散データコレクションを操作するための低レベルAPIです。 RDD APIは、基礎となる物理データ構造を非常に厳密に制御するために使用できる非常に便利なメソッドをいくつか公開しています。これは、異なるマシンに分散されたパーティションデータの不変(読み取り専用)のコレクションです。 RDDを使用すると、大規模クラスターでのメモリ内計算が可能になり、フォールトトレラントな方法でビッグデータ処理を高速化できます。フォールトトレランスを有効にするために、RDDは一連の頂点とエッジで構成されるDAG(Directed Acyclic Graph)を使用します。 DAGの頂点とエッジは、それぞれRDDとそのRDDに適用される操作を表します。 RDDで定義された変換はレイジーであり、アクションが呼び出されたときにのみ実行されます

Spark DataFrame

Spark 1.3では、2つの新しいデータ抽象化API、DataFrameとDataSetが導入されました。 DataFrame APIは、リレーショナルデータベースのテーブルのような名前付き列にデータを整理します。プログラマーは、データの分散コレクションでスキーマを定義できます。 DataFrameの各行は、オブジェクトタイプの行です。 SQLテーブルと同様に、各列にはDataFrame内の同じ行数が必要です。要するに、DataFrameは、データの分散コレクションで実行する必要がある操作を指定する遅延評価プランです。 DataFrameも不変のコレクションです。

Spark DataSet

DataFrame APIの拡張機能として、Spark 1.3には、Sparkで厳密に型指定されたオブジェクト指向プログラミングインターフェイスを提供するDataSet APIも導入されました。これは、不変の、タイプセーフな分散データのコレクションです。 DataFrameと同様に、DataSet APIも実行の最適化を可能にするためにCatalystエンジンを使用します。 DataSetは、DataFrame APIの拡張機能です。

Other Differences-

enter image description here

0
NoName

すべての素晴らしい答えと各APIの使用には、いくらかのトレードオフがあります。データセットは、多くの問題を解決するためのスーパーAPIとして構築されていますが、データを理解し、シングルパスで大量のデータを処理するために処理アルゴリズムが最適化されている場合は、RDDが最適です。

データセットAPIを使用した集計ではまだメモリを消費するため、時間の経過とともに改善されます。

0
Ashkrit Sharma

ADataFrameは、スキーマを持つRDDです。各列に名前と既知の型があるという点で、これをリレーショナルデータベーステーブルと考えることができます。 DataFramesの威力は、構造化データセット(Json、Parquetなど)からDataFrameを作成すると、Sparkが推測できるという事実に由来します。ロードされている(Json、Parquetなど)データセット全体を渡すことによってスキーマを作成します。それから、実行計画を計算するとき、Sparkはスキーマを使うことができて、かなり良い計算最適化をすることができます。 DataFrameは、Spark v1.3.0より前はSchemaRDDと呼ばれていました。

0
user2989087

データフレーム/データセットが構造化データと半構造化データのみを処理できる場合(適切なスキーマを使用している場合)、構造化および非構造化でRDDを使用できます。

0
Raj