You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas中实现与指定SQL多层左连接等价的操作?

嗨Andrew,我来帮你搞定这个Pandas左连接的问题,先理清楚逻辑再给出正确代码~

首先,先拆解你那串SQL的核心逻辑:

SELECT town.id, town.name, county.name AS county, nation.name AS nation
FROM town
LEFT JOIN county ON county.id = town.county_id
LEFT JOIN nation ON nation.id = county.nation_id;

本质是两步左连接:

  1. 以town为主表,通过town.county_id = county.id左连接county表,把区县信息关联到城镇数据上
  2. 再以第一步的结果为主表,通过county.nation_id = nation.id左连接nation表,补充国家/地区信息

你之前的代码问题出在关联键搞反了,而且没指定左连接类型,也没处理重复列名,所以才会出现列名混乱、数据匹配错误的情况。

正确的Pandas实现步骤

假设你已经把三个表的数据分别读到了town_df、county_df、nation_df这三个DataFrame里(对应你给出的三个SELECT语句结果),我们分两步来实现:

第一步:左连接town和county表

这里要明确几个关键参数:

  • how='left':必须显式指定左连接,Pandas默认是内连接,会丢失主表中无匹配的记录
  • left_on='county_id':主表town_df的关联键是county_id
  • right_on='id':被连接表county_df的关联键是自身的id
  • suffixes:给两个表的重复列名加后缀,避免冲突(比如两个表都有name和id)
  • 重命名county_df的name为county,和SQL里的AS county对应

代码:

# 第一步:左连接town和county表
town_county_df = pd.merge(
    town_df,
    county_df,
    how='left',
    left_on='county_id',
    right_on='id',
    suffixes=('_town', '_county')
).rename(columns={'name_county': 'county'})

第二步:左连接nation表

用第一步的结果,通过county_df.nation_id = nation_df.id关联nation表,同样指定左连接,并重命名nation的name列:

# 第二步:左连接nation表
final_df = pd.merge(
    town_county_df,
    nation_df,
    how='left',
    left_on='nation_id',
    right_on='id',
    suffixes=('', '_nation')
).rename(columns={'name': 'nation'})

最后整理成和SQL一致的输出列

如果只需要SQL查询里指定的列,可以做最后一步筛选和重命名:

# 筛选并调整列名,和SQL输出完全匹配
final_df = final_df[['id_town', 'name_town', 'county', 'nation']].rename(
    columns={
        'id_town': 'id',
        'name_town': 'name'
    }
)

用链式调用简化代码

把上面的步骤合并成更简洁的链式写法,可读性也很好:

final_df = (
    pd.merge(town_df, county_df, how='left', left_on='county_id', right_on='id', suffixes=('_town', '_county'))
    .rename(columns={'name_county': 'county'})
    .merge(nation_df, how='left', left_on='nation_id', right_on='id')
    .rename(columns={'name': 'nation'})
    [['id_town', 'name_town', 'county', 'nation']]
    .rename(columns={'id_town': 'id', 'name_town': 'name'})
)

顺便理清merge和join的区别

你提到对df.join()和df.merge()困惑,简单总结:

  • df.join()默认是按索引连接,适合两个表已经有相同索引的场景
  • df.merge()是按指定列连接,更灵活,完全覆盖SQL里的JOIN逻辑,所以你这个场景用merge是正确选择

验证结果的小技巧

你可以检查final_df的行数是否和town_df一致(左连接会保留主表所有记录),再抽查几条数据:比如找一个没有对应county的town,看county列是否为NaN,这符合左连接的特性。

内容的提问来源于stack exchange,提问作者Andrew Holway

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 04:48:13