2つのデータフレームを構築しました。複数のSparkデータフレームを結合するにはどうすればよいですか?
例えば :
PersonDf
、ProfileDf
共通列がpersonId
として(キー)。 PersonDf
とProfileDf
を組み合わせて1つのデータフレームを作成するにはどうすればよいですか?
ケースクラスを使用して、サンプルデータセットを準備できます。これはexのオプションです。hiveContext.sql
からDataFrame
も取得できます。
import org.Apache.spark.sql.functions.col
case class Person(name: String, age: Int, personid : Int)
case class Profile(name: String, personid : Int , profileDescription: String)
val df1 = sqlContext.createDataFrame(
Person("Bindu",20, 2)
:: Person("Raphel",25, 5)
:: Person("Ram",40, 9):: Nil)
val df2 = sqlContext.createDataFrame(
Profile("Spark",2, "SparkSQLMaster")
:: Profile("Spark",5, "SparkGuru")
:: Profile("Spark",9, "DevHunter"):: Nil
)
// you can do alias to refer column name with aliases to increase readablity
val df_asPerson = df1.as("dfperson")
val df_asProfile = df2.as("dfprofile")
val joined_df = df_asPerson.join(
df_asProfile
, col("dfperson.personid") === col("dfprofile.personid")
, "inner")
joined_df.select(
col("dfperson.name")
, col("dfperson.age")
, col("dfprofile.name")
, col("dfprofile.profileDescription"))
.show
私が個人的に好きではない一時テーブルのアプローチのサンプル...
df_asPerson.registerTempTable("dfperson");
df_asProfile.registerTempTable("dfprofile")
sqlContext.sql("""SELECT dfperson.name, dfperson.age, dfprofile.profileDescription
FROM dfperson JOIN dfprofile
ON dfperson.personid == dfprofile.personid""")
注:1)@ RaphaelRothで述べたように、
val resultDf = PersonDf.join(ProfileDf,Seq("personId"))
は、同じテーブルで内部結合を使用している場合、両側から重複する列がないため、適切なアプローチです。
2)Spark 2.xの例が別の回答で更新され、spark 2.xでサポートされる結合操作の完全なセットが追加され、例+結果が追加されました。
また、結合における重要なこと: ブロードキャスト関数はヒントを与えるのに役立ちます私の答えを参照してください
使用できます
val resultDf = PersonDf.join(ProfileDf, PersonDf("personId") === ProfileDf("personId"))
またはより短くて柔軟(結合する複数の列を簡単に指定できるため)
val resultDf = PersonDf.join(ProfileDf,Seq("personId"))
一方通行
// join type can be inner, left, right, fullouter
val mergedDf = df1.join(df2, Seq("keyCol"), "inner")
// keyCol can be multiple column names seperated by comma
val mergedDf = df1.join(df2, Seq("keyCol1", "keyCol2"), "left")
別の方法
import spark.implicits._
val mergedDf = df1.as("d1").join(df2.as("d2"), ($"d1.colName" === $"d2.colName"))
// to select specific columns as output
val mergedDf = df1.as("d1").join(df2.as("d2"), ($"d1.colName" === $"d2.colName")).select($"d1.*", $"d2.anotherColName")
https://spark.Apache.org/docs/1.5.1/api/Java/org/Apache/spark/sql/DataFrame.html から、join
を使用します。
指定された列を使用する別のDataFrameとの内部等結合。
PersonDf.join(ProfileDf,$"personId")
OR
PersonDf.join(ProfileDf,PersonDf("personId") === ProfileDf("personId"))
更新:
df.registerTempTable("tableName")
を使用してDFs
を一時テーブルとして保存し、sqlContext
を使用してSQLクエリを作成することもできます。