当前位置: 首页 > 知识库问答 >
问题:

Spark 数据帧联接 - 重复列(未联接列)

孙京
2023-03-14

我有两个数据帧df1(Employee表)

df1.columns
// Arrays(id,name,dept_id)

df2.columns
// Array(id,name)

在我连接了df1.dept_id和df2.id上的这两个表之后:

val joinedData = df1.join(df2,df1("dept_id")===df2("id"))
joinedData.columns
// Array(id,name,dept_id,id,name)

同时将其保存在文件中,

joined.write.csv("<path>")

它给出错误:

 org.apache.spark.sql.AnalysisException: Duplicate column(s) : "name", "id" found, cannot save to file.;

我读过有关使用字符串序列来避免列重复的信息,但这适用于要对其执行连接的列。我需要对未连接的列具有类似的功能。

有没有一种直接的方法可以将重复列嵌入表名以便保存?

我想出了一个解决方案,匹配两个df的列,并重命名重复的列,将表名附加到列名上。但是有直接的方法吗?

注意:这将是一个通用代码,仅包含执行联接的列详细信息。其余列仅在运行时已知。所以我们不能通过硬编码来重命名列。

共有3个答案

牛智志
2023-03-14

您可以尝试对数据帧使用别名,

import spark.implicits._

df1.as("df1")
  .join(df2.alias("df2"),df1("dept_id") === df2("id"))
  .select($"df1.*",$"df2.*").show()
柳修为
2023-03-14

在进一步研究并获得其他开发人员的意见后,肯定没有直接的方法。一种方法是更改@Raphael指定的所有列的名称。但是我通过只更改重复的列来解决我的问题:

val commonCols = df1.columns.intersect(df2.columns)
val newDf2 = changeColumnsName(df2,commonCols,"df1")

其中更改列名称定义为 :

@tailrec
def changeColumnsName(dataFrame: DataFrame, columns: Array[String], tableName: String): DataFrame = {
if (columns.size == 0)
  dataFrame
else
  changeColumnsName(dataFrame.withColumnRenamed(columns.head, tableName + "_" + columns.head), columns.tail, tableName)

}

现在,执行加入:

val joinedData = df1.join(newDf2,df1("dept_id")===newDf2("df2_id"))
joinedData.columns
// Array(id,name,dept_id,df2_id,df2_name)
董鸣
2023-03-14

我只是通过确保它们具有不同的名称来保留所有列,例如通过在列名之前添加标识符:

val df1Cols = df1.columns
val df2Cols = df2.columns

// prefixes to column names
val df1pf = df1.select(df1Cols.map(n => col(n).as("df1_"+n)):_*)
val df2pf = df2.select(df2Cols.map(n => col(n).as("df2_"+n)):_*)

df1pf.join(df2pf,
    $"df1_dept_id"===$"df2_id",
 )
 类似资料:
  • 我有两个数据帧df1和df2。df1有一个String类型的列键 当df1.key出现在df2.keys中时,我想连接2个数据帧 然而,我正在寻找一个完整的单词匹配。Contains方法连接部分匹配的行。我的意思是,在上面的示例中,我不希望k2与[pk1,pk2]连接,因为数组不包含密钥k2,它包含pk2。 有人能建议如何加入这个案子吗?请用JAVA提供示例。

  • 我正在使用Spark2.3.1和Java。 但它不会停止执行,仍然显示数据集的内容。 然后,在 我得到了错误:

  • 在scala spark中连接不同数据帧时动态选择多列 从上面的链接,我能够让连接表达式工作,但如果列名不同,我们不能使用Seq(columns)而需要动态地连接它。这里的left_ds和right_ds是我想加入的数据流。下面我想要连接列id=acc_id和“acc_no=number”

  • 嗨,伙计们,我正在使用Laravel5.5,我有两个表,用户和服务 用户表 ID 名称 电子邮件 密码 地址 城市 国家 邮政编码 null 提前谢了。热烈问候:阿卜杜拉·沙希德。

  • 我有一个完全相同的文件A和B。我试图在这两个数据帧上执行内部和外部连接。因为我将所有的列都作为重复的列,所以现有的答案没有任何帮助。我遇到的其他问题包含一两个重复的列,我的问题是整个文件都是彼此重复的:无论是数据还是列名。 我的代码: 我面临的错误是:

  • 问题内容: 我的查询有问题。 MySQL查询: 我得到的错误是这样的: 选择时如何将其作为未知列? 我很困扰… 使用者: 兴趣: 已封锁: 问题答案: 如语法所示: 在MySQL 5.0.12中加入处理更改 以前,逗号运算符()和都具有相同的优先级,因此join表达式被解释为。现在具有更高的优先级,因此该表达式被解释为。此更改会影响使用子句的语句,因为该子句只能引用联接操作数中的列,并且优先级的更