【发布时间】:2018-08-18 04:58:44
【问题描述】:
数据框 1:
+---------+---------+
|login_Id1|login_Id2|
+---------+---------+
| 1234567| 1234568|
| 1234567| null|
| null| 1234568|
| 1234567| 1000000|
| 1000000| 1234568|
| 1000000| 1000000|
+---------+---------+
数据帧 2:
+--------+---------+-----------+
|login_Id|user_name| user_Email|
+--------+---------+-----------+
| 1234567|TestUser1|user1_Email|
| 1234568|TestUser2|user2_Email|
| 1234569|TestUser3|user3_Email|
| 1234570|TestUser4|user4_Email|
+--------+---------+-----------+
预期输出
+---------+---------+--------+---------+-----------+
|login_Id1|login_Id2|login_Id|user_name| user_Email|
+---------+---------+--------+---------+-----------+
| 1234567| 1234568| 1234567|TestUser1|user1_Email|
| 1234567| null| 1234567|TestUser1|user1_Email|
| null| 1234568| 1234568|TestUser2|user2_Email|
| 1234567| 1000000| 1234567|TestUser1|user1_Email|
| 1000000| 1234568| 1234568|TestUser2|user2_Email|
| 1000000| 1000000| null| null| null|
+---------+---------+--------+---------+-----------+
我的要求是我必须加入两个数据框,以便从 DataFrame 2 获取每个登录 ID 的附加信息。login_Id1 或 login_Id2 都将有数据(在大多数情况下)。有时这两列也可能有数据。在这种情况下,我想使用 login_Id1 执行连接。当两列不匹配时,我希望 null 作为结果
我点击了这个链接
Join in spark dataframe (scala) based on not null values
我试过了
DataFrame1.join(broadcast(DataFrame2), DataFrame1("login_Id1") === DataFrame2("login_Id") || DataFrame1("login_Id2") === DataFrame2("login_Id") )
我得到的输出是
+---------+---------+--------+---------+-----------+
|login_Id1|login_Id2|login_Id|user_name| user_Email|
+---------+---------+--------+---------+-----------+
| 1234567| 1234568| 1234567|TestUser1|user1_Email|
| 1234567| 1234568| 1234568|TestUser2|user2_Email|
| 1234567| null| 1234567|TestUser1|user1_Email|
| null| 1234568| 1234568|TestUser2|user2_Email|
| 1234567| 1000000| 1234567|TestUser1|user1_Email|
| 1000000| 1234568| 1234568|TestUser2|user2_Email|
| 1000000| 1000000| null| null| null|
+---------+---------+--------+---------+-----------+
当任一列都有值时,我得到了预期的行为。当它们都有值时,对两个列(Row1,Row3)执行连接。在这种情况下 ||不会短路吗?
有没有办法获得预期的数据帧?
到目前为止,我有一个 udf 函数,它检查 login_Id1 是否有值(返回 login_Id1)或 login_Id2 是否有值(返回 login_Id2),如果它们都有值,我将返回 loginId1,并添加 udf 函数的结果作为 DataFrame1 的另一列(Filtered_Login_id)。
使用 udf 添加 FilteredId 列后的 Dataframe1
+--------+---------+-----------+
|loginId1|loginId2 | FilteredId|
+--------+---------+-----------+
| 1234567|1234568 |1234567 |
| 1234567|null |1234567 |
| null |1234568 |1234568 |
| 1234567|1000000 |1234567 |
| 1000000|1234568 |1000000 |
| 1000000|1000000 |1000000 |
+--------+---------+-----------+
然后我根据 FilteredId ===loginId 执行 join 并得到结果
DataFrame1.join(broadcast(DataFrame2), DataFrame1("FilteredId") === DataFrame2("login_Id"),"left_outer" )
有没有更好的方法可以在不使用 udf 的情况下实现此结果?仅使用 join(其行为类似于短路或运算符)?
包括 Leo 指出的用例。我的 udf 方法错过了 Leo 指出的用例。我的确切要求是 2 个输入列值中的任何一个(login_Id1,login_Id2)是否与 Dataframe2 的 login_Id 匹配,即应获取 loginId 数据。如果任一列不匹配,则应添加 null(类似于左外连接)
【问题讨论】:
标签: scala apache-spark