apache-spark - 在 Spark 中执行 DataFrame 自连接的最简洁、最高效的语法

标签 apache-spark dataframe apache-spark-sql

在标准 SQL 中,当您将表与其自身连接时,您可以为表创建别名以跟踪您引用的列:

SELECT a.column_name, b.column_name...
FROM table1 a, table1 b
WHERE a.common_field = b.common_field;

我可以想到两种方法来使用 Spark DataFrame API 实现相同的目的:

解决方案#1:重命名列

在回答 this question时有几种不同的方法。 。这只是重命名具有特定后缀的所有列:

df.toDF(df.columns.map(_ + "_R"):_*)

例如你可以这样做:

df.join(df.toDF(df.columns.map(_ + "_R"):_*), $"common_field" === $"common_field_R")

解决方案 #2:将引用复制到 DataFrame

另一个简单的解决方案就是这样做:

val df: DataFrame = ....
val df_right = df

df.join(df_right, df("common_field") === df_right("common_field"))

这两种解决方案都有效,而且我认为每种解决方案在某些情况下都很有用。我应该注意两者之间有什么内部差异吗?

最佳答案

至少有两种不同的方法可以通过别名来解决此问题:

df.as("df1").join(df.as("df2"), $"df1.foo" === $"df2.foo")

或使用基于名称的相等连接:

// Note that it will result in ambiguous column names
// so using aliases here could be a good idea as well.
// df.as("df1").join(df.as("df2"), Seq("foo"))

df.join(df, Seq("foo"))  

一般来说,列重命名虽然是最丑陋的,但却是所有版本中最安全的做法。存在一些与列解析相关的错误(we found one on SO 不久前),并且如果您使用原始解析器(HiveContext/标准 SQLContext)之间的一些细节可能会有所不同表达式。

我个人更喜欢使用别名,因为它们与惯用的 SQL 相似,并且能够在特定 DataFrame 对象的范围之外使用。

关于性能,除非您对接近实时的处理感兴趣,否则应该没有任何性能差异。所有这些都应该生成相同的执行计划。

关于apache-spark - 在 Spark 中执行 DataFrame 自连接的最简洁、最高效的语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36248652/

相关文章:

apache-spark - 在Spark中禁用 Parquet 元数据摘要

python - Pandas key 错误 : 'occurred at index 0'

scala - Spark数据框为每个现有行添加一行

python - 更改多索引数据帧较低级别中的多个值

python - 当我想检查 Dataframe 是否为空时,“list”对象没有属性 'isEmpty'

scala - Spark : Add column to dataframe conditionally

apache-spark - 在 kubernetes 上运行 spark 文件访问错误

scala - 在 azure HDInsight 应用程序中添加自定义日志

scala - Spark 提交时 ClassNotFoundException scala.runtime.LambdaDeserialize

python - 合并某些行不相同的多个数据框