我是PySpark的新手,因此,如果这有点简单,我很抱歉,我发现其他问题可以比较数据帧,但不是这样的,因此我不认为它是重复的。 我正在尝试比较结构相似的两个日期框架。 “名称”将是唯一的,但计数可能会有所不同。
因此,如果计数不同,我希望它产生一个数据框或python字典。就像下面一样。关于如何实现这样的目标有什么想法吗?
DF1
+-------+---------+
|name | count_1 |
+-------+---------+
| Alice| 1500 |
| Bob| 1000 |
|Charlie| 150 |
| Dexter| 100 |
+-------+---------+
DF2
+-------+---------+
|name | count_2 |
+-------+---------+
| Alice| 1500 |
| Bob| 200 |
|Charlie| 150 |
| Dexter| 10 |
+-------+---------+
产生结果:
不匹配
+-------+-------------+--------------+
|name | df1_count | df2_count |
+-------+-------------+--------------+
| Bob| 1000 | 200 |
| Dexter| 100 | 10 |
+-------+-------------+--------------+
匹配
+-------+-------------+--------------+
|name | df1_count | df2_count |
+-------+-------------+--------------+
| Alice| 1500 | 1500 |
|Charlie| 150 | 150 |
+-------+-------------+--------------+
答案 0 :(得分:1)
对于小型DataFrame比较,可以使用chispa库。在测试套件中执行DataFrame比较时,这特别有用。对于大型数据集,使用联接的公认答案是最好的方法。
在此示例中,chispa.assert_df_equality(df1, df2)
将输出以下错误消息:
不匹配的行为红色,匹配的行为蓝色。 This post有更多有关测试PySpark代码的信息。
有一个很酷的库名为deequ,可用于“数据单元测试”,但是我不确定是否有PySpark实现。
答案 1 :(得分:0)
因此,我创建了第三个DataFrame,将DataFrame1和DataFrame2连接起来,然后按计数字段进行过滤以检查它们是否相等:
不匹配:
df3 = df1.join(df2, [df1.name == df2.name] , how = 'inner' )
df3.filter(df3.df1_count != df3.df2_count).show()
匹配:
df3 = df1.join(df2, [df1.name == df2.name] , how = 'inner' )
df3.filter(df3.df1_count == df3.df2_count).show()
希望这对某人有用
答案 2 :(得分:0)
您可以在每个数据框的顶部创建一个临时视图,并编写Spark SQL查询以进行连接。直接数据框联接和Spark SQL联接是可以在此处探讨的两个选项。 SQL更直观,因此对于新手来说可能很容易。
答案 3 :(得分:0)
MATCH
Df1.join(Df2,Df1.col(“name”) === Df2.col(“name”) && Df1.col(“count_1”) === Df2.col(“count_2”),”inner”).drop(Df2.col(“name”)).show
MISMATCH
Df1.join(Df2,Df1.col(“name”) === Df2.col(“name”) && Df1.col(“count_1”) === Df2.col(“count_2”),”leftanti”).as(“Df3”).join(Df2,Df2.col(“name”) === col(“Df3.name”),”inner”).drop(Df2.col(“name”)).show
答案 4 :(得分:0)
简单的方法是使用spark-extension包中的diff
转换:
from gresearch.spark.diff import *
left = spark.createDataFrame([("Alice", 1500), ("Bob", 1000), ("Charlie", 150), ("Dexter", 100)], ["name", "count"])
right = spark.createDataFrame([("Alice", 1500), ("Bob", 200), ("Charlie", 150), ("Dexter", 10)], ["name", "count"])
diff = left.diff(right, 'name')
diff.show()
+----+-------+----------+-----------+
|diff| name|left_count|right_count|
+----+-------+----------+-----------+
| N| Alice| 1500| 1500|
| C| Bob| 1000| 200|
| N|Charlie| 150| 150|
| C| Dexter| 100| 10|
+----+-------+----------+-----------+
这显示您在一个DataFrame中不匹配(C
)和匹配(N
)。
当然,您可以进行过滤以获取不匹配项和仅匹配项:
diff.where(diff['diff'] == 'C').show()
+----+------+----------+-----------+
|diff| name|left_count|right_count|
+----+------+----------+-----------+
| C| Bob| 1000| 200|
| C|Dexter| 100| 10|
+----+------+----------+-----------+
diff.where(diff['diff'] == 'N').show()
+----+-------+----------+-----------+
|diff| name|left_count|right_count|
+----+-------+----------+-----------+
| N| Alice| 1500| 1500|
| N|Charlie| 150| 150|
+----+-------+----------+-----------+
虽然这是一个简单的示例,但是当涉及到广泛的架构,插入,删除和空值时,差异化DataFrame会变得复杂。