连接不同时,多列的动态选择 Dataframe 在 Scala Spark

我有两个数据帧 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.
有没有办法动态通过列
selectExpr

和细节一起 dataframe, 我们想在我的身上选择它
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

必须指定 dataframe 列继续。 但是,它可能是

如果以下假设为真,甚至更加简化

:


join

on 在两个数据帧中具有相同的名称

所选列具有唯一的名称。 /其他 dataframe 没有具有相同名称的列/

在这种情况下
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/


笔记

: 什么时候
join

使用
Seq[String]

, 由此产生的列的名称 dataframe 与表达式相比会不同。 如果有具有相同名称的列,则在此之后,无法单独选择它们。

八刀丁二

赞同来自:

从上面的略微修改的解决方案是在执行连接之前构成必要的列。 DataFrames, 由于它将具有更少的开销成本,因为可以执行更少的列来执行操作 JOIN.


val dfJoinResult = df1.select/"column1","column2"/.join/df2.select/"col1"/,joinExpr,joinType/


但不要忘记选择要执行连接操作的列,因为首先它将选择列,然后将从可用数据执行连接。

要回复问题请先登录注册