第11章 データセット データセット
この作品はAIを使って翻訳されている。ご意見、ご感想をお待ちしている:translation-feedback@oreilly.com
データセット は、構造化APIの基礎となる型である。我々はすでにDataFramesを扱ったが、これはRow 型のデータセット で、Sparkのさまざまな言語で利用できる。データセット は、厳密にはJava仮想マシン(JVM)言語機能であり、ScalaとJavaでのみ動作する。データセットを使うと、データセットの各行が構成するオブジェクトを定義できる。Scalaでは、これは基本的に使用できるスキーマを定義するケース・クラス・オブジェクトになり、JavaではJava Beanを定義することになる。経験豊富なユーザは、データセットをSparkの「型付きAPIセット」と呼ぶことが多い。詳しくは第4章を参照のこと。
第4章では、SparkにはStringType 、BigIntType 、StructType などの型があることを説明した。これらのSpark固有の型は、String 、Integer 、Double のようなSparkの各言語で利用可能な型にマッピングされる。DataFrame APIを使用する場合、文字列や整数を作成するのではなく、Row オブジェクトを操作することで、Sparkがデータを操作してくれる。実際、Scala や Java を使っている場合、すべての "DataFrame" は実際にはRow 型のデータセットである。ドメイン固有のオブジェクトを効率的にサポートするには、「エンコーディング」と呼ばれる特殊化が必要だ。エンコーディングは、ドメイン固有の型TをSparkの内部型システムにマッピングする。
例えば、name (文字列)とage (int)の2つのフィールドを持つクラスPerson が与えられた場合、エンコーディングは実行時にPerson オブジェクトをバイナリ構造にシリアライズするコードを生成するようにSparkに指示する。DataFramesや "標準的な "Structured APIを使用する場合、このバイナリ構造はRow 。独自のドメイン固有のオブジェクトを作成する場合、Scalaではcase class 、JavaではJavaBean 。Sparkでは、このオブジェクトを(Row の代わりに)分散操作することができる。
Dataset APIを使用する際、このドメインが型を指定する行に触れるたびに、SparkはSpark Row形式を指定したオブジェクト(caseクラスまたはJavaクラス)に変換する。この変換は演算子を遅くするが、より柔軟性を提供できる。プログラミング言語を変えるほど極端なパフォーマンス・コストではないので、Pythonのユーザ定義関数(UDF)のようなものとは桁が違うが、覚えておくべき重要なことだ。
データセットをいつ使うか
、データセットを使うときにパフォーマンス・ペナルティを支払うのであれば、なぜ使う必要があるのだろうかと考えるかもしれない。もし、このことを整理してリスト化するとしたら、以下のような理由がある:
-
実行したい演算がDataFrameの演算式で表現できない場合。
-
型安全性が必要であり、それを達成するために性能の犠牲を厭わない場合
これらをさらに詳しく調べてみよう。これまでの章で見てきた構造化APIでは表現できない演算子もある。特に一般的ではありませんが、SQLやDataFramesではなく、特定の関数でエンコーディングしたい大規模なビジネスロジックがあるかもしれません。これはデータセットに適した使用法である。さらに、データセットAPIは型安全である。例えば2つの文字列型を減算するような、その型に対して妥当でない演算子は、実行時ではなくコンパイル時に失敗する。正しいコードと弾丸のように安全なコードを最優先するのであれば、パフォーマンスを多少犠牲にしても、これは素晴らしい選択となる。これは不正なデータからあなたを守ることはできないが、よりエレガントにデータを扱い、整理することができる。 ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access