如何从pandas DataFrame的姓名列中提取姓氏、身份头衔与名字?
问题原因与解决方案
报错1:TypeError: 'Series' objects are mutable, thus they cannot be hashed
原因
Series.str.replace()的第一个匹配参数要求是字符串/编译后的正则表达式,你传入了df['first_Name']这个Series对象,pandas无法将可变的Series作为匹配规则,因此触发哈希错误。
修复方案
不需要用replace操作,直接沿用拆分逻辑即可实现提取,代码如下:
# 提取姓氏 df['first_Name'] = df['Name'].str.split(',').str.get(0).str.strip() # 提取身份头衔 df['status'] = df['Name'].str.split(',').str.get(1).str.split('.').str.get(0).str.strip() # 提取名字 df['second_name'] = df['Name'].str.split('.').str.get(1).str.strip()
报错2:AttributeError: 'str' object has no attribute 'str'
原因
如果你是对df['Name']列调用apply方法,传入自定义函数的row是每一行的字符串值,不是Pandas的Series对象,因此不能调用只有Series才有.str类方法;同时你自定义函数里的变量命名混乱,返回的second_name、status未定义。
修复方案
不需要自定义函数逐行处理,直接对整个Name列调用str.extract即可一次性提取三个字段,代码更简洁高效:
# 正则一次性提取三个字段 name_part = df['Name'].str.extract(r'(?P<first_name>[^,]+), (?P<status>\w+)\. (?P<second_name>[^(]+)') # 清理名字末尾的空白 name_part['second_name'] = name_part['second_name'].str.strip() # 合并到原数据集 df = pd.concat([df, name_part], axis=1)
如果需要使用自定义函数实现,修正后写法如下:
import re def extract_name_data(name_str): res = re.match(r'(?P<first_name>[^,]+), (?P<status>\w+)\. (?P<second_name>[^(]+)', name_str) if res: return res.group('first_name').strip(), res.group('status').strip(), res.group('second_name').strip() return None, None, None # 应用函数拆分三个字段 df[['first_name', 'status', 'second_name']] = df['Name'].apply(extract_name_data).tolist()
内容的提问来源于stack exchange,提问作者Nikita Tsekhanovich
相关产品推荐
相关产品推荐

