Pandas中如何通过映射字典结合聚合函数填充缺失值
基于关联行求和填充跨县机构缺失值的实现方法
整体逻辑很简单:先把机构-覆盖县域的映射关系展开成关联表,匹配县域统计值后按机构聚合求和,再合并单县域的统计结果即可,全程用pandas基础操作就能实现,不需要复杂函数。
实现步骤
- 第一步:统一名称格式,避免匹配失败
样例数据里存在大小写不一致的问题:映射字典里机构名是Job a格式、县域名是county a全小写,县域统计表里县域名是County a首字母大写,目标结果里机构名是全小写job a,所有名称匹配前必须统一格式,否则会出现匹配不到的空值。 - 第二步:把键值对形式的映射字典展开成二维关联表,每一行对应「机构-下辖单个县域」的关系
- 第三步:关联县域统计表,按机构维度对面积、人口字段求和,得到所有跨县机构的汇总统计值
- 第四步:提取没有被跨县机构覆盖的独立县域,直接把县域名作为机构名、县域统计值作为机构统计值,和跨县机构的汇总结果拼接,就能得到完整的机构统计结果
完整可运行代码
import pandas as pd # ---------------------- 1. 加载基础数据 ---------------------- # 县域统计数据表(表1) df_county = pd.DataFrame({ 'county': ['County a', 'County b', 'County c', 'County d', 'County e', 'County f', 'County g', 'County h', 'County i'], 'sq_mile': [2500, 750, 4000, 4300, 2000, 1000, 4300, 4400, 4000], 'population': [15000, 400, 3500, 4500, 1500, 1500, 3500, 3200, 3500] }) # 跨县机构-覆盖县域映射字典 counties_map = { 'Job a': ['county a', 'county b', 'county c'], 'Job b': ['county d', 'county e', 'county f'], 'Job c': ['county g', 'county h'] } # ---------------------- 2. 处理映射关系 ---------------------- # 字典转长表,统一名称格式 map_rows = [] for org_name, county_list in counties_map.items(): for county_name in county_list: map_rows.append({ 'organization': org_name.lower(), # 机构名转全小写,匹配目标表格式 'county': county_name.title() # 县域名转首字母大写,匹配县域统计表格式 }) df_org_county_map = pd.DataFrame(map_rows) # ---------------------- 3. 聚合跨县机构统计值 ---------------------- df_org_agg = df_org_county_map.merge( df_county, on='county', how='left' ).groupby('organization', as_index=False)[['sq_mile', 'population']].sum() # ---------------------- 4. 补全独立县域的统计值 ---------------------- # 提取所有被跨县机构覆盖的县域 covered_counties = [c.title() for c_list in counties_map.values() for c in c_list] # 筛选未被覆盖的独立县域,转换为机构表结构 df_single_org = df_county[~df_county['county'].isin(covered_counties)].copy() df_single_org = df_single_org.rename(columns={'county': 'organization'}) df_single_org['organization'] = df_single_org['organization'].str.lower() # 拼接跨县机构+独立县域结果 final_result = pd.concat( [df_org_agg, df_single_org[['organization', 'sq_mile', 'population']]], ignore_index=True )
结果验证
执行print(final_result)就能得到需要的目标输出:
organization sq_mile population 0 job a 7250 18900 1 job b 7300 7500 2 job c 8700 6700 3 county i 4000 3500
补充说明
- 如果你已经有提前建好的、带NaN缺失值的机构表(表2),不需要重新构造结果,只需要把上面得到的
final_result和原表做左连接,用聚合后的值覆盖原来的NaN列即可:# 假设df_org是你已有的带缺失值的表2 df_org = df_org.drop(columns=['sq_mile', 'population']).merge(final_result, on='organization', how='left') - 后续新增跨县机构时,只需要往
counties_map字典里添加对应的键值对,代码不需要做任何修改。
内容的提问来源于stack exchange,提问作者brandooo23
相关产品推荐
相关产品推荐

