我有2个数据集。
示例数据集1:
id | model | first_name | last_name
-----------------------------------------------------------
1234 | 32 | 456765 | [456700,987565]
-----------------------------------------------------------
4539 | 20 | 123211 | [893456,123456]
-----------------------------------------------------------
有时first_name和last_name列之一为空。
示例数据集2:
number | matricule | name | model
----------------------------------------------------------
AA | 0009 | 456765 | 32
----------------------------------------------------------
AA | 0009 | 893456 | 32
----------------------------------------------------------
AA | 0009 | 456700 | 32
----------------------------------------------------------
AA | 0008 | 456700 | 32
----------------------------------------------------------
AA | 0008 | 987565 | 32
对于一个matricule
,我们可以找到更多的name
和model
,就像上面的示例一样。
我应该怎么做:
对于数据集1中的每一行,我采用3列:模型,first_name和last_name,并在数据集2中查找它们(如果存在/根据矩阵元素匹配)。
我应该比较:
每个模型的模型==>如果模型(数据集1)存在于模型(数据集2)==>匹配中
如果名字中存在名字==>则不匹配。如果名字中不存在first_name ==>匹配
如果在name ==>匹配项中存在last_name。当我有两个last_name值时,两者都应存在于要匹配的数据集2的名称中。
示例:
数据集1中的行1为:
id | model | first_name | last_name
------------------------------------------------------
1234 | 32 | 456765 | [456700,987565]
对于数据集2中的矩阵0009,我有:
number | matricule | name | model
----------------------------------------------------------
AA | 0009 | 456765 | 32
----------------------------------------------------------
AA | 0009 | 893456 | 32
----------------------------------------------------------
AA | 0009 | 456700 | 32
所以:
当材料= 0009 ==>不匹配时,数据集2的名称中存在first_name(456765)
姓氏,仅存在456700 ==>不匹配
数据集2的模型中存在模型(32)==>匹配
所以我跳过了矩阵0009。然后将数据集1中的第二行与矩阵0008的元素进行比较。
对于数据集2中的矩阵0008,我有:
----------------------------------------------------------
AA | 0008 | 456700 | 32
----------------------------------------------------------
AA | 0008 | 987565 | 32
我们总是在数据集1的第一行中
矩阵= 0008 ==>匹配时,数据集2的名称中不存在first_name(456765)
last_name,当矩阵= 0008,==>匹配时,两个值都存在于数据集2的名称中
当矩阵= 0008 ==>匹配时,数据集2的模型中存在模型
找到所有匹配项后,我将创建一个包含以下内容的新数据集:
number | id | matricule
-----------------------------------
AA | 1234 | 0008
-----------------------------------
我希望我很清楚。有人可以帮我。
答案 0 :(得分:1)
您可以在匹配条件下使用join。
首先,您可以将第二个DataFrame分组,并将name
列收集到一个列表中:
df2 = df2.groupBy("number", "model", "matricule").agg(collect_list("name").alias("names"))
f2.show(truncate=False)
#+------+-----+---------+------------------------+
#|number|model|matricule|names |
#+------+-----+---------+------------------------+
#|AA |32 |0009 |[456765, 893456, 456700]|
#|AA |32 |0008 |[456700, 987565] |
#+------+-----+---------+------------------------+
现在,加入df1
和df2
。对于条件1和2,检查起来很简单。
对于第三个,您可以使用Spark 2.4+提供的array_except
(last_name
列中的元素不应该包含在names
中,反之亦然):
join_condition = (col("df1.model") == col("df2.model")) \
& ~expr("array_contains(df2.names, df1.first_name)") \
& (size(expr("array_except(df2.names, df1.last_name)")) == lit(0)) \
& (size(expr("array_except(df1.last_name, df2.names)")) == lit(0))
df_result = df1.alias("df1").join(df2.alias("df2"), join_condition)
最后,从联接结果中选择所需的列:
df_result.select("number", "id", "matricule").show(truncate=False)
#+------+----+---------+
#|number|id |matricule|
#+------+----+---------+
#|AA |1234|0008 |
#+------+----+---------+