Apache spark 验证一个pyspark数据帧中与另一个数据帧匹配的行数据
我有2个Pyspark数据帧df1,df2。df1和df2都包含数百万条记录 df1类似于:Apache spark 验证一个pyspark数据帧中与另一个数据帧匹配的行数据,apache-spark,pyspark,apache-spark-sql,pyspark-sql,pyspark-dataframes,Apache Spark,Pyspark,Apache Spark Sql,Pyspark Sql,Pyspark Dataframes,我有2个Pyspark数据帧df1,df2。df1和df2都包含数百万条记录 df1类似于: +-------------------+--------+--------+ | name|state | pincode| +-------------------+--------+--------+ | CYBEX INTERNATION| HOUSTON| 00530 | | FLUID POWER| MEDWAY | 02053 | |
+-------------------+--------+--------+
| name|state | pincode|
+-------------------+--------+--------+
| CYBEX INTERNATION| HOUSTON| 00530 |
| FLUID POWER| MEDWAY | 02053 |
| REFINERY SYSTEMS| FRANCE | 072234 |
| K N ENTERPRISES| MUMBAI | 100010 |
+-------------------+--------+--------+
df2类似于:
+--------------------+--------+--------+
| name |state | pincode|
+--------------------+--------+--------+
|FLUID POWER PVT LTD | MEDWAY | 02053 |
| CYBEX INTERNATION | HOUSTON| 02356 |
|REFINERY SYSTEMS LTD| MUMBAI | 072234 |
+--------------------+--------+--------+
所以,我想根据名称状态和Pincode检查是否在df2上找到df1,如果验证了输出,即找到的行将为1,否则为0,df将为
+-------------------+--------+--------+--------- --+
| name|state | pincode| Validated |
+-------------------+--------+--------+---------- -+
| CYBEX INTERNATION| HOUSTON| 00530 | 0 |
| FLUID POWER| MEDWAY | 02053 | 1 |
| REFINERY SYSTEMS| FRANCE | 072234 | 0 |
| K N ENTERPRISES| MUMBAI | 100010 | 0 |
+-------------------+--------+--------+------------+
在第一种情况下,df1 Pincode的第1行与任何df2 Pincode列都不匹配,因此已验证=0
在第二种情况下,df1 Pincode的第2行匹配,状态也匹配,对于name列,我使用Levenshtein匹配列名,最后一行验证为=1
第三行中的Pincode匹配,但状态不匹配且已验证=0
在4rth中,Pincode不存在且已验证=0
在嵌套if中迭代数据时,我尝试了Pandas dataFrame,但数据太大,迭代不是一个好的选择
我希望使用pyspark和利用并行处理来加快流程,例如:
df_final = df1.withColumn('validated', if some_expression == True THEN 1,ELSE 0)
但无法找出一些_表达式,以及如何在另一个具有给定列且无需任何迭代的df2上检查整个df1验证
我经历过不同的火花问题和类似的问题,但没有一个对我有帮助。
任何帮助都将不胜感激。如果有任何信息不清楚,请发表评论。使用with left join可以执行以下操作:
join_condition = (col("df1.pincode") == col("df2.pincode")) \
& (levenshtein(col("df1.name"), col("df2.name")) <= 10) \
& (col("df1.state") == col("df2.state"))
result_df = df1.alias("df1").join(df2.alias("df2"), join_condition , "left")
result_df.select("df1.*",
when(col("df2.name").isNotNull(), lit(1)).otherwise(lit(0)).alias("validated")
).show()
#+-----------------+-------+-------+---------+
#| name| state|pincode|validated|
#+-----------------+-------+-------+---------+
#|CYBEX INTERNATION|HOUSTON| 00530| 0|
#| FLUID POWER| MEDWAY| 02053| 1|
#| REFINERY SYSTEMS| FRANCE| 072234| 0|
#| K N ENTERPRISES| MUMBAI| 100010| 0|
#+-----------------+-------+-------+---------+
如果你有确切的名字,你可以使用左连接。但我认为您需要基于levenshtein距离匹配名称@SreeramTP,因为列名中的名称在两个数据帧中的长度都不固定,而且其排列也不确定,这就是为什么必须应用一些模糊逻辑或levenshtein距离方法的原因。正如您所说,您可以在conditionHi@blackbishop中使用left join with我尝试过df1.joindf2,[df1.pincode==df2.pincode,df1.state==df2.state,levenshteindf1.name,df2.nameHi,@blackbishop我也尝试过在我的答案中包括df2的几列。我尝试过列表中的列名,即cols=[df1.col1,df1.col2,df2.col1]result_df.select*cols,whencoldf2.name.isNotNull,lit1.otherwiselit0.aliasvalidated.show但显示语法错误:只有命名参数可能跟在*expression后面。此外,我已将两个表中的列名都更改为唯一,但仍然没有得到结果,只有此语法错误。