使用NLTK提取姓名后保存CSV遇TypeError及格式与追加需求
解决NLTK提取姓名存CSV的报错与格式问题
我帮你梳理下问题根源,再一步步给出解决方案:
报错原因分析
你的first_and_last_names函数只是打印了处理后的姓名,没有返回任何有效数据,所以names = first_and_last_names(text)得到的是None。而csv.writer.writerows()要求接收可迭代的序列(比如列表、元组),自然就抛出TypeError了。
修正代码并实现姓名列拆分
我们需要修改函数让它返回拆分好的「名字+姓氏」二维列表,这样写入CSV时就能自动分成两列。同时处理下NER识别出的异常姓名(比如你例子里的General, Services, Peter),避免列混乱:
from nltk import tokenize, pos_tag, ne_chunk from nameparser import HumanName # 假设你用这个库解析姓名 def get_human_names(text): tokens = tokenize.word_tokenize(text) pos = pos_tag(tokens) sentt = ne_chunk(pos) person_list = [] person = [] name = "" for subtree in sentt.subtrees(filter=lambda t: t.label() == 'PERSON'): for leaf in subtree.leaves(): person.append(leaf[0]) if len(person) > 1: # 过滤单独的姓氏 for part in person: name += part + ' ' cleaned_name = name[:-1] if cleaned_name not in person_list: person_list.append(cleaned_name) name = '' person = [] return person_list def first_and_last_names(text): name_list = get_human_names(text) formatted_names = [] for name in name_list: human_name = HumanName(name) # 处理异常姓名,只取第一部分姓氏/名字 last_name = human_name.last.split(',')[0] if human_name.last else '' first_name = human_name.first.split(',')[0] if human_name.first else '' formatted_names.append([first_name, last_name]) # 顺序:名字列在前,姓氏列在后 return formatted_names # 假设text是你的源文本 names = first_and_last_names(text) # 写入CSV(带表头) import csv with open('westtrannames.csv', 'w', newline='') as csvFile: writer = csv.writer(csvFile) writer.writerow(['名字', '姓氏']) # 可选:写入表头 writer.writerows(names) # 无需手动close,with语句会自动管理文件
向CSV追加后续结果
如果要向同一个文件追加新数据,只需要把打开模式从'w'(覆盖写入)改成'a'(追加模式),同时判断文件是否存在,避免重复写入表头:
import csv def append_names_to_csv(name_data, filename='westtrannames.csv'): # 判断文件是否已存在 file_exists = False try: with open(filename, 'r') as f: file_exists = True except FileNotFoundError: pass with open(filename, 'a', newline='') as csvFile: writer = csv.writer(csvFile) if not file_exists: writer.writerow(['名字', '姓氏']) writer.writerows(name_data) # 示例:追加新文本提取的姓名 new_names = first_and_last_names(new_text) append_names_to_csv(new_names)
额外提示
你例子里的General, Services, Peter和Parnership, Rail明显是NER识别错误的结果,后续可以加个过滤逻辑(比如排除包含「General」「Services」这类非姓名关键词的条目),提升数据准确性。
内容的提问来源于stack exchange,提问作者Rachel9866
相关产品推荐
相关产品推荐

