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

Spacy列表推导式处理Pandas DataFrame提取人名报错排查

问题:用Spacy提取DataFrame人名时的列表推导式错误排查

你有这样一个Pandas DataFrame:

import pandas as pd
df = pd.DataFrame({
    'Text': [
        "When can I go to Canada?",
        "Who is king Arthur?",
        "Can you give me the email of Norton?"
    ]
})

你想要提取每行里的人名,得到这样的结果:

IndexTextName
0When can I go to Canada?
1Who is king Arthur?Arthur
2Can you give me the email of Norton?Norton

你最初用df['Name'] = [nlp(x).ents for x in df['Text']]提取实体,但会把所有类型的实体(比如Canada这种地名)都捞出来,不符合需求。于是你改成了这段代码:

df['Name'] = [token.label_ for token in nlp(x).ents for x in df['Text']]

结果直接触发了NameError: name 'x' is not defined,这到底是哪里出问题了?

错误原因分析

这个列表推导式的循环顺序完全搞反了!

列表推导式的嵌套循环是按从左到右的顺序执行的,你写的[token.label_ for token in nlp(x).ents for x in df['Text']],逻辑上是先尝试遍历nlp(x).ents里的每个token,但这时候x还没被定义——因为遍历df['Text']的循环被放在了最后!

Python会先解析最内层的循环条件,当它试图调用nlp(x)时,x还没有被赋值,自然就抛出NameError了。而且就算顺序改对,你现在取的是token.label_(也就是实体类型,比如PERSON),而不是实体的文本内容,这也达不到你提取人名的目的。

正确的写法

你需要先遍历DataFrame里的每一行文本,再对每个文本的实体筛选出类型为PERSON的,提取它们的文本;如果没有符合条件的实体,就留空。

可以用这样的列表推导式:

import spacy
nlp = spacy.load("en_core_web_sm")

df['Name'] = [
    ', '.join([ent.text for ent in nlp(text).ents if ent.label_ == 'PERSON']) 
    for text in df['Text']
]

简单解释下:

  • 外层循环遍历df['Text']里的每一段文本text
  • 内层遍历这段文本的所有实体ent,只保留类型是PERSON的,提取它们的文本内容
  • 用, 把多个人名(如果有的话)拼接起来,没有符合条件的就返回空字符串

运行这段代码后,就能得到你期望的结果啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 15:57:34