Pandas DataFrame长文本列按长度和句子边界智能分割教程

碧海醫心
发布: 2025-09-27 11:03:12
原创
569人浏览过

pandas dataframe长文本列按长度和句子边界智能分割教程

本文介绍如何利用NLTK和Pandas库,将DataFrame中包含超长描述性文本的列,智能地分割成多个符合指定最大长度限制的新列。该方法确保每个分割后的文本块都以完整的句子结束,有效解决了数据导入导出时字符长度限制的问题,同时保持了文本的语义完整性。

挑战与需求

在数据处理过程中,我们经常会遇到DataFrame中某些文本列(例如产品描述、用户评论等)的字符串长度远超常规限制(如数据库字段限制、API请求体大小限制)。直接截断文本会导致句子不完整,影响语义。因此,一个常见的需求是:

  1. 将超长文本列分割成多个子列。
  2. 每个子列的文本长度不超过一个预设的最大值(例如300个字符)。
  3. 最关键的是,每个子列的文本都必须以完整的句子结束,避免句子被截断。

传统的基于分隔符或固定长度的分割方法无法同时满足“长度限制”和“句子完整性”这两个条件。

解决方案概述

为了解决上述挑战,我们将结合使用以下工具和策略:

  • NLTK (Natural Language Toolkit):用于对文本进行句子级别的分词(nltk.sent_tokenize),确保我们能够识别和处理完整的句子。
  • 自定义Python函数:编写一个灵活的函数,该函数接收原始长文本和最大长度限制,然后根据NLTK分割的句子,智能地组合成符合长度要求且句子完整的文本块。
  • Pandas apply 和 join 方法:将自定义函数高效地应用到DataFrame的指定列上,并将生成的新列无缝地整合回原始DataFrame。

环境准备

在开始之前,请确保您的Python环境中已安装pandas和nltk库。如果尚未安装,可以通过以下命令进行安装:

pip install pandas nltk
登录后复制

此外,NLTK需要下载其punkt分词器,用于支持sent_tokenize功能。首次使用时,请运行以下代码下载:

序列猴子开放平台
序列猴子开放平台

具有长序列、多模态、单模型、大数据等特点的超大规模语言模型

序列猴子开放平台 0
查看详情 序列猴子开放平台
import nltk
nltk.download('punkt')
登录后复制

核心实现:自定义文本分割函数

我们将创建一个名为split_sentences的函数,它接收原始长文本、最大长度限制和新列的前缀作为参数。

import pandas as pd
import nltk

def split_sentences(text, max_len=300, prefix='col'):
    """
    将长文本按句子边界和最大长度限制分割成多个字符串。

    参数:
    text (str): 待分割的原始文本。
    max_len (int): 每个分割块的最大字符长度。
    prefix (str): 生成新列的前缀名称。

    返回:
    pd.Series: 包含分割后文本块的Pandas Series,索引为新列名。
    """
    out = [] # 存储最终的文本块
    current_chunk_sentences = [] # 存储当前正在构建的文本块中的句子
    current_chunk_len = 0 # 存储当前文本块的实际长度

    # 使用NLTK将文本分割成句子
    sentences = nltk.sent_tokenize(text)

    for sentence in sentences:
        # 计算当前句子加入后,块的长度(包括句子间的空格)
        # 如果是块中的第一个句子,不加空格;否则加一个空格
        sentence_effective_len = len(sentence) + (1 if current_chunk_sentences else 0)

        # 检查将当前句子加入到当前块是否会超过max_len
        # 并且确保当前块不为空(避免在第一个句子就超长时创建空块)
        if current_chunk_len + sentence_effective_len > max_len and current_chunk_sentences:
            # 如果会超长,则将当前已有的句子组合成一个块并添加到结果中
            out.append(' '.join(current_chunk_sentences))
            current_chunk_sentences = [] # 清空,开始新的文本块
            current_chunk_len = 0        # 重置新块的长度

        # 将当前句子添加到当前文本块
        current_chunk_sentences.append(sentence)
        # 更新当前文本块的长度
        current_chunk_len += sentence_effective_len

    # 循环结束后,将最后一个未添加到out的文本块添加进去(如果存在)
    if current_chunk_sentences:
        out.append(' '.join(current_chunk_sentences))

    # 将结果转换为Pandas Series,并重命名索引为col_1, col_2等
    return pd.Series(out).rename(lambda x: f'{prefix}_{x+1}')
登录后复制

函数逻辑详解:

  1. 初始化:out列表用于存储最终分割出的文本块,current_chunk_sentences存储当前正在构建的文本块中的句子,current_chunk_len记录当前块的字符总长度。
  2. 句子分词:使用nltk.sent_tokenize(text)将输入文本分割成独立的句子列表。
  3. 迭代句子:遍历每个句子。
  4. 长度检查:在将句子添加到current_chunk_sentences之前,我们计算如果加入该句子,当前块的总长度会是多少。这里需要注意,如果current_chunk_sentences不为空,则在句子之间需要添加一个空格,所以sentence_effective_len会额外加1。
  5. 块分割判断:如果current_chunk_len + sentence_effective_len超过了max_len,并且current_chunk_sentences不为空(确保不是因为第一个句子就超长而导致空块),则认为当前块已满。此时,将current_chunk_sentences中的所有句子用空格连接起来,形成一个完整的文本块,并添加到out中。然后清空current_chunk_sentences和current_chunk_len,为下一个文本块做准备。
  6. 添加句子:无论是否发生块分割,当前句子都会被添加到current_chunk_sentences中,并更新current_chunk_len。
  7. 处理最后一个块:循环结束后,current_chunk_sentences中可能还剩下未添加到out的句子。因此,需要检查并将其作为最后一个文本块添加。
  8. 返回Series:最终,out列表被转换为一个Pandas Series,其索引被重命名为prefix_1, prefix_2等,方便后续与DataFrame合并。

整合到DataFrame

将上述split_sentences函数应用到DataFrame的指定列,并合并结果。

# 示例数据框
lipsum = '''Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit.'''
df = pd.DataFrame({'other': [1, 2], 'text': [lipsum, lipsum.upper()]})

print("原始DataFrame:")
print(df)
print("\n" + "="*50 + "\n")

# 应用自定义函数并合并结果
# df['text'].apply(split_sentences) 会对'text'列的每个元素(即每个长文本)调用split_sentences函数
# 每个调用返回一个Series,df.join() 会将这些Series作为新列添加到DataFrame中
# drop(columns='text') 移除原始的长文本列
result_df = df.join(df['text'].apply(split_sentences, max_len=300, prefix='text_chunk')).drop(columns='text')

print("分割后的DataFrame:")
print(result_df)
登录后复制

输出示例:

原始DataFrame:
   other                                               text
0      1  Lorem ipsum dolor sit amet, consectetur adipis...
1      2  LOREM IPSUM DOLOR SIT AMET, CONSECTETUR ADIPIS...

==================================================

分割后的DataFrame:
   other                                        text_chunk_1  \
登录后复制

以上就是Pandas DataFrame长文本列按长度和句子边界智能分割教程的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号