Python中如何更新DataFrame每行的元组列表,为指定单词添加自定义标签
问题修复方案
核心错误原因
你出现长度不匹配报错的根源是:pos_tags是遍历单行时生成的当前行对应的元组列表,长度等于该行的单词数量(报错中的23就是单条数据的元组个数),但你在循环结束后直接把单条数据的列表赋值给了有500行的整列df['title'],二者长度完全不匹配,因此抛出值错误。
此外代码还存在几个逻辑问题:
- 你给
enumerate设置了start=1,但Python列表索引从0开始,后续执行pos_tags[position] = tuple_时会出现索引越界、元素错位修改的问题 - 冗余的
new_text.append逻辑没有实际作用,还会占用内存 - 多列匹配时会重复包裹标签,可按需调整逻辑
修正后代码
import re # 提前初始化存储所有行处理结果的列表 processed_title = [] cols = list(df.columns)[4:] for idx, row in df.iterrows(): doc = nlp(row['title']) pos_tags = [(token.text, token.pos_) for token in doc if not token.pos_ == "PUNCT"] # 枚举保留0起始索引用于修改列表,position单独存位置序号 for idx_in_sent, tuple_ in enumerate(pos_tags): position = idx_in_sent + 1 word = tuple_[0] spacy_pos_tag = tuple_[1] word = re.sub(r'[^\w\s]', '', word) # 匹配到任意一列就加标签,避免多列匹配重复包裹可以加break for col in cols: if position in row[col]: word = f'<{col.upper()}>{word}</{col.upper()}>' # 如果不需要多标签叠加,这里加break即可 # 用正确的0起始索引修改列表元素 pos_tags[idx_in_sent] = (word, spacy_pos_tag) # 把当前行处理好的元组列表加入总结果 processed_title.append(pos_tags) # 总结果长度和df行数一致,直接赋值即可 df['title'] = processed_title print(df.title)
修改关键点说明
- 提前创建
processed_title列表收集所有行的处理结果,最终赋值给df['title']时总长度和df的500行完全匹配,不会再出现长度错误 - 拆分了列表索引和位置序号,避免索引越界问题
- 去掉了冗余的无效代码,逻辑更简洁
- 可根据需求选择是否允许多个标签叠加包裹,不需要的话在匹配到对应列后加
break即可
内容的提问来源于stack exchange,提问作者joasa
相关产品推荐
相关产品推荐

