Spark-如何避免联接后出现重复的列?

时间:2018-07-02 23:40:05

标签: scala apache-spark join apache-spark-sql

扩展此处给出的用例: How to avoid duplicate columns after join?

我有两个带有100列的数据框。以下是带有连接列的一些示例:

df1.columns
//  Array(ts, id, X1, X2, ...)

df2.columns
//  Array(ts, id, X1, Y2, ...)

我这样做之后:

val df_combined = df1.join(df2, df1.X1===df2.X1 and df1.X2==df2.Y2)

我最后得到以下几列:Array(ts, id, X1, X2, ts, id, X1, Y2)X1是重复的。

我不能使用join(right: Dataset[_], usingColumns: Seq[String]) api,因为要使用此api,所有列都必须存在于两个数据帧中,而此处不是这种情况(X2Y2)。我看到的唯一选择是重命名列并稍后删除列,或者重命名数据框并稍后从第二个数据框中删除列。 没有简单的API可以实现这一目标吗?例如。在进行等价联接时会自动删除联接列之一。

1 个答案:

答案 0 :(得分:3)

如您所述,避免重复列的最佳方法是使用Seq[String]作为join的输入。但是,由于这些列在数据框中的名称不同,因此只有两个选项:

  1. Y2列重命名为X2,并以join的身份执行df1.join(df2, Seq("X1", "X2"))。如果以后要同时保留Y2X2列,只需将X2复制到新列Y2

  2. 像以前一样执行join,之后再drop执行不需要的重复列:

    df1.join(df2, df1.col("X1") === df2.col("X1") and df1.col("X2") == df2.col("Y2"))
      .drop(df1.col("X1"))
    

不幸的是,当前没有自动的方法可以实现这一目标。


加入数据框时,最好确保它们没有相同的列名(join中使用的列除外)。例如,上面的tsid列。如果有很多列,可能很难手动重命名它们。要自动执行此操作,可以使用以下代码:

val prefix "df1_"
val cols = df1.columns.map(c => col(c).as(s"$prefix$c"))
df1.select(cols:_*)