dataframe—处理spark scala api交叉连接的最佳方法,该交叉连接导致右Dataframe和左Dataframe的列名相同

envsm3lx  于 2021-05-29  发布在  Spark
关注(0)|答案(2)|浏览(421)

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

val df = Seq((2, "b"), (3, "a"), (5, "z")).toDF("number", "letter")
val dfCrossJoin = df.crossJoin(df)
dfCrossJoined.select("letter")

引发异常:

...
Message: Reference 'letter: is ambiguous
...

为了避免这些模糊性错误,一个解决方案是能够重命名右Dataframe或左Dataframe的所有列。有没有办法用scalaapi实现这一点?目前,我找到了一个使用SQLAPI的解决方案(见下文),但我想知道是否有更好的方法来解决这个问题(是编程重命名还是选择无歧义列的方法)。

val df = Seq((2, "b"), (3, "a"), (5, "z")).toDF("number", "letter")
df.createOrReplaceTempView("df")
val dfCrossJoinedSql = spark.sql(s"""
select 
  t1.*, 
  ${df.columns.map(c => s"t2.${c} as ${c}_2").mkString(", ")}
from 
 df t1 cross join df t2
""")
r3i60tvu

r3i60tvu1#

为了更干净,你可以用 .withColumnRenamed() 重命名列,然后删除列。

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()
1zmg4dgp

1zmg4dgp2#

可以在连接之前使用别名对Dataframe进行别名 .as() :

val df = Seq((2, "b"), (3, "a"), (5, "z")).toDF("number", "letter")
val dfCrossJoined = df.as("left").crossJoin(df.as("right"))
dfCrossJoined.select("right.letter")

相关问题