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

如何在Pandas中按姓氏首字母分类生成姓名字典

按姓氏首字母分组的全名字典构建方案

需求说明

需要生成一个字典,将所有姓名按**姓氏首字母(大写英文字母)**分组,每个字母键对应一个子列表,存储该首字母姓氏的全名,示例格式如下:

{'A': ['V. Aakalu',
       'J.L. Accini',
       'Kimberly A. Aeling',
       'Konstantin Afanaciev',
       'T. Afzar',
       'Heidi Agnic'],

'B': ['Nicholas P. Breznay',
       'B. Breznock',
       'Rebecca Brincks',
       'M.A. Brito Sanfiel',
       'Reinhard Brunmeir']
....
}

遇到的问题

  1. 所有姓名出现在每个字母的列表中:用dict.fromkeys(string.ascii_uppercase, [])初始化字典后,所有字母键共享同一个空列表,追加姓名时所有键的列表都会同步更新。
  2. 姓名被覆盖:使用update()方法时,每个字母键最终只保留最后一个赋值的姓名,之前的内容被覆盖。

错误原因分析

  • dict.fromkeys的第二个参数如果是可变对象(比如列表),所有键会指向同一个对象引用,并非每个键独立创建新列表。
  • update()方法用于替换字典的键值对,直接赋值字符串会覆盖原本的列表类型,导致每个键只能存储单个值。

最优解决方案

方案一:基于Pandas的高效实现(推荐)

利用Pandas的分组功能直接处理DataFrame,代码简洁且效率高:

import pandas as pd
import string

# 1. 生成全名列(名 + 空格 + 姓)
main_db['full_name'] = main_db['auth_name'] + ' ' + main_db['auth_surname']

# 2. 过滤掉姓氏为空的行
valid_data = main_db.dropna(subset=['auth_surname']).copy()

# 3. 提取姓氏首字母并转为大写
valid_data['surname_initial'] = valid_data['auth_surname'].str[0].str.upper()

# 4. 拆分英文字母首字母和非英文字母/特殊字符的行
english_data = valid_data[valid_data['surname_initial'].isin(string.ascii_uppercase)]
non_english_data = valid_data[~valid_data['surname_initial'].isin(string.ascii_uppercase)]

# 5. 分组生成目标字典
name_dict = english_data.groupby('surname_initial')['full_name'].apply(list).to_dict()

# 6. 处理非英文字母的姓名(可选)
unnorm_dict = {}
if not non_english_data.empty:
    unnorm_dict['Non-English'] = non_english_data['full_name'].tolist()

方案二:基础循环实现

手动初始化独立列表,遍历DataFrame行处理:

import string
import pandas as pd

# 初始化字典,每个字母键对应独立的空列表(关键:避免共享引用)
name_dict = {char: [] for char in string.ascii_uppercase}
unnorm_dict = {'Non-English': []}

# 遍历每一行数据
for _, row in main_db.iterrows():
    surname = row['auth_surname']
    # 跳过姓氏为空的行
    if pd.isna(surname):
        continue
    
    full_name = f"{row['auth_name']} {surname}"
    first_char = surname[0].upper()
    
    if first_char in name_dict:
        name_dict[first_char].append(full_name)
    else:
        unnorm_dict['Non-English'].append(full_name)

# 可选:对每个子列表按姓氏排序
for key in name_dict:
    name_dict[key].sort()

原代码问题修正点

  1. 字典初始化错误:将norm_dict = dict.fromkeys(string.ascii_uppercase, [])改为norm_dict = {char: [] for char in string.ascii_uppercase},确保每个键拥有独立列表。
  2. 遍历逻辑简化:无需将DataFrame转为字典,直接用iterrows()遍历行更直观。
  3. 避免覆盖问题:使用append()向列表添加元素,而非update()替换键值对。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 09:03:46