Spark Scala中基于多OR条件实现Accounts与Customers DataFrame左连接
解决多条件OR左连接的问题
嘿,我来帮你搞定这个DataFrame左连接的需求!你需要基于三个OR条件把Accounts和Customers左连接,保留Accounts的所有记录对吧?刚好你的示例里每个匹配场景都覆盖到了,我直接给你上可运行的代码和解释~
第一步:构造示例数据
首先我们先把你给的两个DataFrame用pandas构造出来,确保和你的数据一致:
import pandas as pd # 构建Accounts表 accounts_data = { 'Name': ['AR', 'BR', 'CR', 'KR'], 'Id': [1, 2, 3, 4], 'Telephone': ['123', '213', '231', '132'], 'Mob': ['1234', '4123', '3214', '1324'], 'email': ['test1@gmail.com', 'test2@gmail.com', 'test3@gmail.com', 'test4@gmail.com'] } Accounts = pd.DataFrame(accounts_data) # 构建Customers表 customers_data = { 'Id': [2, 6, 7], 'Phone': ['2344', '132', '64562'], 'Email': ['testq@gmail.com', 'testf@gmail.com', 'test1@gmail.com'] } Customers = pd.DataFrame(customers_data)
第二步:实现多OR条件的左连接
因为pandas的merge默认只支持AND逻辑的连接条件,要实现OR逻辑的话,我们可以先做交叉连接(把每个Accounts记录和所有Customers记录配对),再筛选出满足任一条件的行,最后再和原Accounts表左连接确保所有记录都保留:
# 1. 做交叉连接(笛卡尔积),让每个Accounts和Customers都配对 cross_join = Accounts.assign(temp_key=1).merge(Customers.assign(temp_key=1), on='temp_key').drop('temp_key', axis=1) # 2. 筛选满足任一匹配条件的行:Id匹配 / Phone匹配Telephone或Mob / Email匹配email matched_rows = cross_join[ (cross_join['Id_x'] == cross_join['Id_y']) | (cross_join['Phone'] == cross_join['Telephone']) | (cross_join['Phone'] == cross_join['Mob']) | (cross_join['Email'] == cross_join['email']) ] # 3. 左连接回原Accounts表,每个Accounts只保留第一个匹配结果(按需调整keep参数) final_result = Accounts.merge( matched_rows.drop_duplicates(subset='Id_x', keep='first'), left_on='Id', right_on='Id_x', how='left' ).drop(['Id_x', 'Id_y'], axis=1)
第三步:查看结果
运行上面的代码后,final_result就是你想要的结果啦:
Name Id Telephone Mob email Phone Email 0 AR 1 123 1234 test1@gmail.com 64562 test1@gmail.com 1 BR 2 213 4123 test2@gmail.com 2344 testq@gmail.com 2 CR 3 231 3214 test3@gmail.com NaN NaN 3 KR 4 132 1324 test4@gmail.com 132 testf@gmail.com
小提示
如果某个Accounts记录同时满足多个匹配条件(比如既匹配Id又匹配Email),drop_duplicates里的keep参数可以调整:
keep='first':保留第一个匹配到的记录(默认)keep='last':保留最后一个匹配到的记录keep=False:保留所有匹配到的记录
内容的提问来源于stack exchange,提问作者upenkas
相关产品推荐
相关产品推荐

