重命名后如何检查火花列的相等性

Posted

技术标签:

【中文标题】重命名后如何检查火花列的相等性【英文标题】:How to check equality of spark columns after renaming 【发布时间】:2016-09-29 20:04:44 【问题描述】:

我正在尝试为 Java Spark-Sql 应用程序编写一些测试。我需要测试的一个操作重命名了一个列,并且在将重命名列的实际值与我的预期值进行比较时遇到了一些困难。经过一些实验,我能够编写以下两个测试来演示该问题:

首先,作为健全性检查,我尝试了这个(df 是 spark sql DataFrame,通过从我正在测试的 json 文件中读取一些示例数据生成):

  @Test
  public void testColumnEquality() throws Exception 
    Column val1 = df.col("col2");
    Column val2 = df.col("col2");
    Assert.assertEquals(val1, val2);
  

正如人们所期望的那样,它通过了。然后我尝试了这个:

  @Test
  public void testReanmeColumnEquality() throws Exception 
    Column val1 = df.col("col2").as("col2");
    Column val2 = df.col("col2").as("col2");
    Assert.assertEquals(val1, val2);
  

失败并出现错误java.lang.AssertionError: expected:<col2 AS col2#4L> but was:<col2 AS col2#5L>

挖掘 scala 代码(完全公开 - 我对 scala 知之甚少)看起来这与 NamedExpression 唯一 ID 有关。

有什么方法可以合理地检查这两列是否代表具有相同别名的相同操作?

(我正在使用 spark 1.6,理想情况下希望为该版本行提供解决方案,但如果这在 2.0 中得到修复,那也是很好的信息。)

谢谢。

【问题讨论】:

【参考方案1】:

我写了a blog post关于如何解决这个问题:

诀窍是:检查Expression 是否具有Alias trait:

`column.expr() instanceof Alias`

如果是,则使用提取器模式解压缩子表达式和名称:

alias = (Alias) column.expr()
Option<Tuple2<Expression, String>> aliasTuple = Alias$.MODULE$.unapply(alias);

【讨论】:

你能用 Scala 做吗?【参考方案2】:

我进行了一些挖掘,看起来在实例化新列的过程中,关于带有别名的 Column 的孩子的信息丢失了。可能某处有状态可以查询,但是没找到。

所以这不是一个答案,但希望它对某人有用或感兴趣。

更多信息

Column 对象上的as 方法的定义是指name 函数(请参阅Column.scala),它只调用定义Alias 的案例类here。 Alias(及其child)未暴露。它直接提供给ColumnwithExpr 函数,该函数基于Alias 命名表达式实例化一个新列。

因此,您要么直接比较列上 toString 的结果(丢失有关列来自何处的信息,即哪个数据框),要么您实际解析由 @ 打印的字符串 打印 987654334@ 方法...但对我来说似乎并不明智...

【讨论】:

以上是关于重命名后如何检查火花列的相等性的主要内容,如果未能解决你的问题,请参考以下文章

在火花中重命名 S3 文件是不是会将文件加载到内存中

使用文件名列表重命名批处理文件

将.SD与重命名的变量相结合,会使.SD列的名称混乱。

php检查文件名是不是存在,重命名文件

重命名sql结果列的通用方法

R语言dplyr包通过数据列的索引重命名数据列实战(Rename Column by Index Position)