如何用Pandas实现1:n关系表的Left Join并保持左表行数
解决1:n表Left Join后保持左表行数并合并重复数据的问题
我完全懂你的需求——你希望在处理1:n关系的两张表左连接时,不把关联的多行数据展开成单独行,而是把同一主键对应的重复值用分号;拼接成单个字符串,最终结果的行数和左表(国家表)保持一致。
常规的merge操作确实会把每个关联的城市拆成独立行,要实现你想要的效果,我们可以先对右表(城市表)做分组聚合,再和左表做连接,具体步骤如下:
步骤1:准备示例数据(可直接替换为你的实际数据)
先还原你的示例表结构:
import pandas as pd # 国家表(左表) country = pd.DataFrame({ 'CountryID': [1, 2], 'Country': ['UK', 'Russia'], 'Area': [1029, 8374] }) # 城市表(右表,与国家表是1:n关系) city = pd.DataFrame({ 'CountryID': [1, 1, 2, 2], 'City': ['London', 'Manchester', 'Moscow', 'Ufa'] })
步骤2:聚合城市表,合并同一国家的城市
对城市表按CountryID分组,将每个分组内的City字段用分号拼接成单个字符串:
# 分组聚合,合并城市名称 city_aggregated = city.groupby('CountryID')['City'].agg(';'.join).reset_index() # 重命名列名,避免后续合并时混淆 city_aggregated.rename(columns={'City': 'Cities'}, inplace=True)
这一步执行后,city_aggregated的结构会变成:
CountryID Cities 0 1 London;Manchester 1 2 Moscow;Ufa
步骤3:与国家表执行左连接
现在用处理后的城市表和国家表做左连接,就能得到你期望的结果:
# 左连接,确保结果行数与国家表一致 final_result = country.merge(city_aggregated, how='left', on='CountryID')
最终输出的final_result就是你想要的格式:
CountryID Country Area Cities 0 1 UK 1029 London;Manchester 1 2 Russia 8374 Moscow;Ufa
额外优化:处理空值场景
如果存在部分国家没有对应城市的情况,Cities列会出现NaN,你可以用fillna把空值替换为空字符串:
final_result['Cities'] = final_result['Cities'].fillna('')
内容的提问来源于stack exchange,提问作者Sabih
相关产品推荐
相关产品推荐

