Spark DataFrame的`except()`每次都会删除不同的项目

时间:2017-12-11 22:48:26

标签: scala apache-spark

var df = List(1,2,3,4,5,6,7,8,9,10,11).toDF("num")
df.show()
var df2 = df.limit(3)
df2.show()
var df3 =  df.except(df2)
df3.show()

令人惊讶的是,我发现除了不应该按照它应该的方式工作。这是我的输出: df2:正确创建,包含1,2和3.但是我的df3仍然有1,2和/或3。这有点随意。如果我多次运行它,我会得到不同的结果。谁能帮帮我吗?提前致谢。

3 个答案:

答案 0 :(得分:3)

你需要设置一个火花"动作"收集" df2"所需的数据在执行"除了"操作,这将确保数据帧df2得到预先计算,并具有将从df中减去的固定内容。

随机性是因为火花懒惰的评估和火花将你的所有代码放在一个阶段。以及" df2"的内容当你执行&#34时没有修复,除了"操作就可以了。根据限制的spark函数定义:

  

通过获取第一个n行返回新的数据集。这个功能的区别       而headhead是一个动作并返回一个数组(通过触发查询执行)      而limit返回一个新的数据集。

从那以后,它返回一个datset,将是懒惰的评估,

下面的代码将为您提供一致的输出。

var df = List(1,2,3,4,5,6,7,8,9,10,11).toDF("num")
df.show()
var df2 = df.head(3).map(f => f.mkString).toList.toDF("num")
df2.show()
var df3 =  df.except(df2)
df3.show()

答案 1 :(得分:0)

测试此方法的最佳方法是创建一个具有您想要差异的值的新DF。

val df = List(1,2,3,4,5,6,7,8,9,10,11).toDF("num")
df.show()
val df2 = List(1,2,3).toDF("num")
df2.show()
val df3 =  df.except(df2)
df3.show()

或者,只需编写确定性过滤器以选择所需的行:

val df = List(1,2,3,4,5,6,7,8,9,10,11).toDF("num")
df.show()
val df2 = df.filter("num <= 3")
df2.show()
val df3 =  df.except(df2)
df3.show()

答案 2 :(得分:0)

如果您要比较的列中具有唯一性,则可以为此使用leftanti连接。

示例:

var df = List(1,2,3,4,5,6,7,8,9,10,11).toDF("num")  
df.show()  
var df2 = df.limit(3)  
df2.show()  
var df3 =  df.join(df2,Seq("num"),"leftanti")  
df3.show()