![](/img/trans.png)
[英]Converting multiple different columns to Map column with Spark Dataframe scala
[英]Dynamically select multiple columns while joining different Dataframe in Scala Spark
我有兩個火花數據幀df1
和df2
。 有沒有辦法在加入這兩個數據幀時動態選擇輸出列? 在內連接的情況下,以下定義輸出來自df1和df2的所有列。
def joinDF (df1: DataFrame, df2: DataFrame , joinExprs: Column, joinType: String): DataFrame = {
val dfJoinResult = df1.join(df2, joinExprs, joinType)
dfJoinResult
//.select()
}
輸入數據:
val df1 = List(("1","new","current"), ("2","closed","saving"), ("3","blocked","credit")).toDF("id","type","account")
val df2 = List(("1","7"), ("2","5"), ("5","8")).toDF("id","value")
預期結果:
val dfJoinResult = df1
.join(df2, df1("id") === df2("id"), "inner")
.select(df1("type"), df1("account"), df2("value"))
dfJoinResult.schema():
StructType(StructField(type,StringType,true),
StructField(account,StringType,true),
StructField(value,StringType,true))
我查看了df.select(cols.head, cols.tail: _*)
等選項df.select(cols.head, cols.tail: _*)
但它不允許從兩個DF中選擇列。 有沒有辦法動態傳遞selectExpr
列以及我們想要從我的def
選擇它的數據幀詳細信息? 我正在使用Spark 2.2.0。
可以將select
表達式作為Seq[Column]
傳遞給方法:
def joinDF(df1: DataFrame, df2: DataFrame , joinExpr: Column, joinType: String, selectExpr: Seq[Column]): DataFrame = {
val dfJoinResult = df1.join(df2, joinExpr, joinType)
dfJoinResult.select(selectExpr:_*)
}
要調用方法,請使用:
val joinExpr = df1.col("id") === df2.col("id")
val selectExpr = Seq(df1.col("type"), df1.col("account"), df2.col("value"))
val testDf = joinDF(df1, df2, joinExpr, "inner", selectExpr)
這將產生預期的結果:
+------+-------+-----+
| type|account|value|
+------+-------+-----+
| new|current| 7|
|closed| saving| 5|
+------+-------+-----+
在上面的selectExpr
,有必要指定列來自哪個數據幀。 但是, 如果滿足以下假設 ,則可以進一步簡化 :
join
的列在兩個數據框中具有相同的名稱 在這種情況下,可以將joinExpr: Column
更改為joinExpr: Seq[String]
和selectExpr: Seq[Column]
以選擇selectExpr: Seq[String]
:
def joinDF(df1: DataFrame, df2: DataFrame , joinExpr: Seq[String], joinType: String, selectExpr: Seq[String]): DataFrame = {
val dfJoinResult = df1.join(df2, joinExpr, joinType)
dfJoinResult.select(selectExpr.head, selectExpr.tail:_*)
}
現在調用方法看起來更干凈:
val joinExpr = Seq("id")
val selectExpr = Seq("type", "account", "value")
val testDf = joinDF(df1, df2, joinExpr, "inner", selectExpr)
注意 :使用Seq[String]
執行join
,與使用表達式相比,結果數據幀的列名稱將不同。 當存在具有相同名稱的列時,之后將無法單獨選擇這些列。
從上面給出的一個稍微修改過的解決方案是在執行連接之前,事先從DataFrames中選擇所需的列,因為它將具有較少的開銷,因為執行JOIN操作的列數較少。
val dfJoinResult = df1.select("column1","column2").join(df2.select("col1"),joinExpr,joinType)
但請記住選擇要執行連接操作的列,因為它將首先選擇列,然后從可用數據中選擇連接操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.