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

使用NLTK去除停用词失败求助:分词正常但停用词未移除

问题分析与解决

你的停用词移除功能失效主要有两个核心问题:

  • return语句位置错误:remove_stopwords函数里的return text写在for循环内部,导致循环只执行一次就直接返回结果,根本没遍历完所有单词,自然没法移除所有停用词。
  • 遍历列表时直接修改原列表的风险:用for word in text遍历同时执行text.remove(word),会导致迭代器跳过部分元素,即使修正return位置,也可能出现漏删的情况。

另外你的预处理函数还会产生空字符串,建议一并处理。

修正后的完整代码

import re
import nltk
from nltk.corpus import stopwords

def pre_process(text):
    # 移除特殊字符和数字
    text = re.sub(r"(\d|\W|_)+", " ", text)
    # 分词并过滤空字符串
    text = [word for word in re.split(r"\W+", text) if word]
    return text

# 下载停用词
nltk.download('stopwords')
# 转成集合提升查询效率
stop_words = set(stopwords.words('english'))

def remove_stopwords(text):
    # 用列表推导式生成不含停用词的新列表,避免修改原列表导致的迭代问题
    return [word for word in text if word not in stop_words]

# 应用预处理和停用词移除
text = dat['text'].apply(lambda x: pre_process(x))
text_stopword = text.apply(lambda x: remove_stopwords(x))

关键修改说明

  1. 调整return位置:把返回逻辑移到循环外部(直接用列表推导式替代循环更简洁),确保所有单词都被检查。
  2. 改用集合存储停用词:stopwords.words('english')是列表,查询word in 列表的时间复杂度是O(n),转成集合后是O(1),处理大量数据时效率更高。
  3. 过滤空字符串:预处理时用列表推导式过滤掉re.split产生的空字符串,避免后续处理无效内容。
  4. 用列表推导式替代循环删除:直接生成新的不含停用词的列表,比遍历删除原列表更安全、高效,不会出现迭代跳过元素的问题。

测试修正后的代码,the、in、of这类停用词就会被正确移除了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 01:48:19