说明
Spark并没有提供比较两个dataframe是否相等的函数,所以,需要通过现有的函数来完成任务。但不同方式的性能有很大不同。
这里提供4种方式来比较两个Dataframe是否相等,可以根据不同的场景来选择使用。
实现方案
-
对于小的dataframe,可以直接collect回来,然后比较。
-
(1)先检查表结构是否相等;(2)确保df1,df2,df3没有重复行 ,使用intersect,并查看其count数是否和df的count数相等
-
使用subtract函数
可以通过subtract函数来计算两个df的不同数据行,若没有不同数据行,则表示这两个df是相等的。代码如下:
df1 = spark.range(100) df2 = spark.range(100) df3 = spark.range(23) assert df1.subtract(df2).count() == df2.subtract(df1).count() == 0
这种方式的代价会比较大,但不受df中数据行顺序的限制。其实这里,若不关心是否有重复的行,可以把groupBy运算去掉。
-
使用subtract函数+take()
这种方法是3的变种,其实我们可以不用计算所有不同数据行的总行数,其实只要有一行就是不同的,根据这个思路,我们可以使用take:
# 比较两个df是否相等的函数: # 1.比较schema 2.比较数据行 # def match_df(df1, df2): # 1.比较schema # todo: # 2.比较数据 count1 = len(df1.subtract(df2).take(1)) count2 = len(df2.subtract(df1).take(1)) return True if count1 == count2 and count1 == 0 else False # 使用函数 df1 = spark.range(100) df2 = spark.range(100) df3 = spark.range(23) r = match_df(df1, df2) print r # 输出:True r = match_df(df1, df3) print r # 输出:False
通过take来替代了count(),可以使得效率得到提高。
小结
本文提供了如何比较dataframe的几种方法,可以根据实际情况选择使用。