处理Spark Scala API交叉连接的最佳方法是为右侧和左侧数据帧提供相同的列名称

处理Spark Scala API交叉连接的最佳方法是为右侧和左侧数据帧提供相同的列名称,scala,dataframe,apache-spark,Scala,Dataframe,Apache Spark,在Spark Scala API中使用crossJoin时,输出的列具有相同的名称,这会由于歧义而导致错误。例如: val df=Seq((2,“b”),(3,“a”),(5,“z”)。toDF(“数字”,“字母”) val dfCrossJoin=df.crossJoin(df) dfCrossJoined.select(“字母”) 引发异常: ... Message: Reference 'letter: is ambiguous ... 为了避免这些模糊性错误,一个解决方案是能够重命名

在Spark Scala API中使用
crossJoin
时,输出的列具有相同的名称,这会由于歧义而导致错误。例如:

val df=Seq((2,“b”),(3,“a”),(5,“z”)。toDF(“数字”,“字母”)
val dfCrossJoin=df.crossJoin(df)
dfCrossJoined.select(“字母”)
引发异常:

...
Message: Reference 'letter: is ambiguous
...
为了避免这些模糊性错误,一个解决方案是能够重命名右数据帧或左数据帧的所有列。 有没有办法用Scala API做到这一点? 目前,我找到了一个使用SQLAPI的解决方案(见下文),但我想知道是否有更好的方法来实现这一点(是编程重命名还是选择列而不产生歧义)

val df=Seq((2,“b”),(3,“a”),(5,“z”)。toDF(“数字”,“字母”)
df.createOrReplaceTempView(“df”)
val dfCrossJoinedSql=spark.sql“”
挑选
t1.*,
${df.columns.map(c=>s“t2.${c}作为${c}\u 2”).mkString(“,”)}
从…起
df t1交叉连接df t2
""")

您可以在连接之前使用
.as()
对数据帧进行别名:

val df=Seq((2,“b”),(3,“a”),(5,“z”)。toDF(“数字”,“字母”)
val dfcrossjoin=df.as(“左”)。交叉连接(df.as(“右”))
dfCrossJoined.select(“right.letter”)

对于更干净的方式,您可以使用
.WithColumnRename()
重命名列,然后删除列

val df = Seq((2, "b"), (3, "a"), (5, "z")).toDF("number", "letter")
val dfCrossJoin = df.crossJoin(testDF.withColumnRenamed("letter","rletter"))
                 .drop("rletter")

dfCrossJoin.select(col("letter")).show()