云计算百科
云计算领域专业知识百科平台

NLP预处理Python内置函数_02_分词辅助与过滤筛选

NLP 预处理必备的 Python 内置函数(二):分词辅助与过滤筛选

写在前面:上一篇我们把「文本清洗」和「文本规范化」讲透了(strip()、replace()、re.sub()、lower()、unicodedata.normalize() 等)。本篇进入流水线的中间环节——分词辅助 与 过滤筛选。

文本洗白之后,就要把它切成一个个 token(词),再把噪声 token(停用词、空串、纯数字)过滤掉。这中间用到的方法,全部是 Python 内置,零第三方依赖。


目录

  • 分词与切分辅助
  • 过滤与筛选
  • 综合实战:完整的过滤清洗流水线
  • 小结

  • 一、分词与切分辅助

    1. str.split() —— 分词的主力工具

    语法

    str.split(sep=None, maxsplit=1)

    参数说明

    参数类型说明
    sep str,可选 分隔符。不传时按任意空白(空格、\\t、\\n)切分,且自动过滤空串;传入时严格按该字符串切分,空串会保留
    maxsplit int,可选 最大切分次数,-1 表示不限次数

    返回值:返回字符串列表。

    示例代码

    # 不传 sep:按任意空白切分,自动处理多个空格
    s = " hello world python "
    print(s.split()) # ['hello', 'world', 'python']

    # 传 sep:严格按分隔符切分,空串会保留
    s2 = "a,,b,c"
    print(s2.split(",")) # ['a', '', 'b', 'c'] ← 注意中间的空串

    # maxsplit 限制次数
    s3 = "a,b,c,d"
    print(s3.split(",", 2)) # ['a', 'b', 'c,d'] ← 只切前 2 次

    # 中文按标点切分
    s4 = "自然语言处理,人工智能,机器学习"
    print(s4.split(",")) # ['自然语言处理', '人工智能', '机器学习']

    NLP 场景应用

    # 英文按空白分词(最常用)
    sentence = "I love natural language processing"
    tokens = sentence.split()
    print(tokens) # ['I', 'love', 'natural', 'language', 'processing']

    # 解析 CSV 行
    row = "张三,25,北京,工程师"
    fields = row.split(",")
    print(fields) # ['张三', '25', '北京', '工程师']

    注意事项(高频易错点)

  • "a b".split() 和 "a b".split(" ") 结果不一样:前者自动合并连续空白并去空串,后者遇到连续空格会产生空串;
  • 中文分词不要直接用 split()(中文词之间没有空格),交给 jieba 这类分词库;split() 只负责按标点/空白粗切。

  • 2. str.join() —— 分词的逆操作

    语法

    str.join(iterable)

    参数说明

    参数类型说明
    iterable 可迭代对象 列表、元组、生成器等,元素必须是字符串

    返回值:用调用者字符串作为分隔符,拼接各元素后返回新字符串。

    示例代码

    print(" ".join(["I", "love", "Python"])) # "I love Python"
    print(",".join(["a", "b", "c"])) # "a,b,c"
    print("".join(["a", "b", "c"])) # "abc"
    print("-".join("abc")) # "a-b-c"(字符串本身可迭代)

    # 生成器也可以
    print("|".join(str(i) for i in range(3))) # "0|1|2"

    NLP 场景应用

    # 分词 → 处理 → 重组句子(比如去掉停用词后再拼回去)
    tokens = ["我", "喜欢", "的", "Python"]
    filtered = [t for t in tokens if t != "的"]
    print(" ".join(filtered)) # "我 喜欢 Python"

    # 生成 CSV 行
    row = ["张三", "25", "北京"]
    print(",".join(row)) # "张三,25,北京"

    注意事项(高频易错点)

  • 元素必须是字符串:",".join([1, 2, 3]) 会抛 TypeError,需要先 map(str, …) 转换;
  • 大量字符串拼接时,join() 效率远高于 +(+ 是 O(n²),join() 是 O(n)),批量拼接永远优先 join()。

  • 3. str.splitlines() —— 按行切分

    语法

    str.splitlines([keepends])

    参数说明

    参数类型说明
    keepends bool,可选 是否在结果中保留换行符,默认 False 去掉

    返回值:按换行符(\\n、\\r\\n、\\r 等)切分后的字符串列表。

    示例代码

    text = "第一行\\r\\n第二行\\n第三行\\r第四行"
    print(text.splitlines())
    # ['第一行', '第二行', '第三行', '第四行']

    # 保留换行符
    print("a\\nb".splitlines(True)) # ['a\\n', 'b']

    # 对比:split("\\n") 处理不了 \\r\\n
    print("a\\r\\nb".split("\\n")) # ['a\\r', 'b'] ← 残留 \\r,需再 strip

    NLP 场景应用

    # 按行读取并清洗语料(比 split("\\n") 更健壮)
    with open("corpus.txt", encoding="utf-8") as f:
    lines = [line.strip() for line in f.read().splitlines()]

    注意事项

    splitlines() 能识别全部 Unicode 换行符,跨平台处理文本(Windows \\r\\n、Unix \\n、Mac \\r)时比 split("\\n") 可靠得多。


    4. str.find() 与 str.index() —— 定位子串

    语法

    str.find(sub[, start[, end]]) # 找不到返回 -1
    str.index(sub[, start[, end]]) # 找不到抛 ValueError
    str.rfind(sub) # 从右侧开始找
    str.rindex(sub)

    返回值:子串首次出现的索引(int)。

    示例代码

    s = "自然语言处理是人工智能的一个分支"

    print(s.find("人工智能")) # 7(0 起始索引)
    print(s.find("不存在")) # -1

    print(s.index("人工智能")) # 7
    # print(s.index("不存在")) # 会抛 ValueError: substring not found

    print(s.rfind("的")) # 从右往左找

    # 指定搜索范围
    print("hello world".find("o", 5)) # 7,从索引 5 开始找

    NLP 场景应用

    • 定位敏感词位置做脱敏:

    def mask_sensitive(text, keyword):
    idx = text.find(keyword)
    if idx == 1:
    return text
    return text[:idx] + "*" * len(keyword) + text[idx + len(keyword):]

    print(mask_sensitive("我的手机号是13812345678", "13812345678"))
    # "我的手机号是***********"

    注意事项

    find() 返回 -1 表示找不到、不会抛异常,适合"判断在不在";index() 找不到直接报错,适合"确定存在再取位置"的场景。不确定存在性时优先 find()。


    5. str.startswith() 与 str.endswith() —— 首尾判断

    语法

    str.startswith(prefix[, start[, end]]) # prefix 可以是字符串或元组
    str.endswith(suffix[, start[, end]])

    返回值:布尔值。

    示例代码

    s = "人工智能在自然语言处理中的应用"

    print(s.startswith("人工")) # True
    print(s.startswith("自然")) # False
    print(s.endswith("应用")) # True

    # 元组参数:满足其中一个即可
    url = "https://example.com"
    print(url.startswith(("http://", "https://"))) # True

    # 指定范围判断
    print("hello world".endswith("world")) # True

    NLP 场景应用

    • 过滤掉以特殊字符开头/结尾的噪声行:

    lines = ["# 标题", "正文内容", "【广告】xxx", "——分割线——"]
    clean = [l for l in lines
    if not l.startswith(("#", "【"))
    and not l.endswith("——")]
    print(clean) # ['正文内容']


    二、过滤与筛选

    6. filter() —— 函数式过滤

    语法

    filter(function, iterable)

    参数说明

    参数类型说明
    function 函数 / None 返回 True 的元素被保留;传 None 时过滤掉所有"假值"(空串、0、None 等)
    iterable 可迭代对象 待过滤的数据

    返回值:Python 3 中返回迭代器(惰性求值),需要用 list() 等转成列表。

    示例代码

    nums = [1, 0, 5, 3, 8]
    print(list(filter(lambda x: x > 0, nums))) # [1, 5, 8]

    # function 为 None:过滤假值
    data = ["hello", "", "world", None, 0]
    print(list(filter(None, data))) # ['hello', 'world']

    NLP 场景应用

    # 去空串 + 去停用词,一条 filter 搞定
    stopwords = {"的", "了", "和", "是"}
    tokens = ["我", "爱", "的", "Python", "", "是"]

    clean = list(filter(
    lambda w: w and w not in stopwords,
    tokens
    ))
    print(clean) # ['我', '爱', 'Python']

    注意事项

    filter() 是惰性的,直接 print(filter(…)) 看到的是迭代器对象;务必包一层 list()。想同时做转换(比如 str()),可以 map() + filter() 连用,或直接上列表推导式。


    7. len() —— 长度过滤与统计

    语法

    len(obj)

    返回值:对象长度。字符串返回字符数,列表/字典返回元素个数。

    示例代码

    print(len("自然语言处理")) # 6,中文字符按 1 个字符计
    print(len(["a", "b", "c"])) # 3
    print(len({})) # 0

    NLP 场景应用

    • 过滤过短的噪声 token(单字、空白串):

    tokens = ["我", "爱", "自然语言处理", "Python", "的"]
    meaningful = [t for t in tokens if len(t) >= 2]
    print(meaningful) # ['自然语言处理', 'Python']("我""爱""的"长度1被过滤)

    • 截断超长文本(限制模型输入长度):

    def truncate(text, max_len=200):
    return text[:max_len] if len(text) > max_len else text

    注意事项

    对中文分词结果用 len() 时注意:中文按字符计数,英文 token 按字母计数,两者的"长度"语义不同,过滤阈值要分别设定。


    8. str.isalpha() / isdigit() / isalnum() —— 字符类型判断

    语法

    str.isalpha() # 是否全是字母(中文也返回 True)
    str.isdigit() # 是否全是数字
    str.isalnum() # 是否全是字母或数字
    str.isdecimal() # 是否全是十进制数字(比 isdigit 更严格)
    str.isnumeric() # 是否全是数字字符(比 isdigit 更宽松)

    返回值:布尔值。

    示例代码

    print("abc".isalpha()) # True
    print("自然语言".isalpha()) # True ← 中文也算字母!
    print("abc123".isalpha()) # False

    print("123".isdigit()) # True
    print("abc".isdigit()) # False

    print("abc123".isalnum()) # True
    print("abc 123".isalnum()) # False(空格不是字母数字)

    三类数字判断的区别(易混淆,重点记)

    方法识别内容示例
    isdigit() 0-9 及部分 Unicode 数字 "²".isdigit() → True
    isdecimal() 仅十进制数字(最严格) "²".isdecimal() → False
    isnumeric() 数字字符(含中文数字、罗马数字) "三".isnumeric() → True

    NLP 场景应用

    # 过滤纯数字 token(对情感分析等任务通常是噪声)
    tokens = ["房价", "30000", "元", "2024年"]
    clean = [t for t in tokens if not t.isdigit()]
    print(clean) # ['房价', '元', '2024年']

    # 识别中文(利用 isalpha 对中文返回 True 的特性)
    def is_chinese_text(s):
    return all('\\u4e00' <= ch <= '\\u9fff' for ch in s)

    注意事项

  • isalpha() 对中文返回 True,想只判断英文字母需配合正则 [a-zA-Z];
  • 处理文本中的年份"2024年"这类混合串时,isdigit() 返回 False,需要 re.search(r'\\d+', t) 判断是否含数字。

  • 9. set() —— 去重与建词表

    语法

    set(iterable)

    返回值:去重后的集合(无序)。

    示例代码

    words = ["我", "爱", "Python", "我", "爱", "编程"]
    print(set(words)) # {'编程', '我', '爱', 'Python'}(顺序不固定)

    NLP 场景应用

    # 快速统计唯一词数量(词表大小)
    vocab = set(tokens)
    print(f"词表大小:{len(vocab)}")

    # 词表转索引字典(需要稳定顺序时先排序)
    vocab = sorted(set(tokens))
    word2idx = {w: i for i, w in enumerate(vocab)}

    注意事项

  • set() 是无序的,每次运行顺序可能不同;
  • 需要固定顺序建词表时,用 sorted(set(…)) 或 dict.fromkeys(tokens)(Python 3.7+ 字典保序):# 按首次出现顺序去重
    ordered_unique = list(dict.fromkeys(words))
    # ['我', '爱', 'Python', '编程']

  • 10. map() —— 批量转换

    语法

    map(function, iterable, ...)

    返回值:迭代器(惰性),需 list() 转换。

    示例代码

    nums = ["1", "2", "3"]
    print(list(map(int, nums))) # [1, 2, 3]

    # 多参数:zip 风格并行传入
    a = [1, 2, 3]
    b = [10, 20, 30]
    print(list(map(lambda x, y: x + y, a, b))) # [11, 22, 33]

    NLP 场景应用

    # 分词结果统一转小写 / 去空格
    tokens = [" Hello ", "WORLD", "Python "]
    clean = list(map(lambda t: t.strip().lower(), tokens))
    print(clean) # ['hello', 'world', 'python']

    # join 前批量转字符串
    nums = [1, 2, 3]
    print(",".join(map(str, nums))) # "1,2,3"

    注意事项

    map() 惰性求值,且参数是函数在前、可迭代对象在后,和 filter() 的传参顺序一致,别写反。


    三、综合实战:完整的过滤清洗流水线

    把第 2 篇的方法组合成一段可复用的过滤函数:

    import re

    STOPWORDS = {"的", "了", "和", "是", "在", "有", "我", "你"}

    def filter_tokens(tokens, min_len=1, stopwords=None):
    """分词结果过滤:去空串、去停用词、去纯数字、去过短 token"""
    stopwords = stopwords or STOPWORDS
    return [
    t for t in tokens
    if t # 非空
    and t not in stopwords # 非停用词
    and not t.isdigit() # 非纯数字
    and len(t) >= min_len # 长度达标
    and t.isalnum() # 只保留字母/中文/数字组合(去掉标点 token)
    ]

    def tokenize_and_filter(text):
    # 清洗 → 分词 → 过滤
    text = re.sub(r'[^\\w\\s\\u4e00-\\u9fff]', ' ', text)
    tokens = text.split()
    return filter_tokens(tokens)

    text = "我 爱 Python!的 自然语言处理 是 2024 最热门的 方向 !!!"
    print(tokenize_and_filter(text))
    # ['爱', 'Python', '自然语言处理', '最热门的', '方向']

    可以看到:我/的/是(停用词)、2024(纯数字)、!!!(标点)都被过滤掉了,剩下的是有实际语义的 token。


    四、小结

    本篇覆盖了流水线的中间两个阶段:

    • 分词辅助:split()(按空白/分隔符切分)、join()(重组)、splitlines()(按行)、find() / index()(定位)、startswith() / endswith()(首尾判断);
    • 过滤筛选:filter()(函数式过滤)、len()(长度过滤)、isalpha() / isdigit() 家族(类型判断)、set()(去重建词表)、map()(批量转换)。

    下一篇(系列完结篇)将讲解 统计、建词表与完整实战:collections.Counter、sorted()、enumerate()、zip()、ord() / chr()、isinstance(),并给出一段从原始文本到词表索引的全流程可运行代码。敬请关注。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » NLP预处理Python内置函数_02_分词辅助与过滤筛选
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!