txt、pdf等文件转为一行一行的doccano数据集输入格式

文章目录

    • doccano 数据集导入
    • 简介
    • 代码实现
    • 代码运行结果
    • 代码公开

doccano 数据集导入

在这里插入图片描述

在Doccano 导入数据集时,使用TextLine的文件格式,导入的文件需要为一行一行文本的数据格式,每一行文本在导入Doccano后就是一条数据。

简介

主要工作说明:把pdf转成txt文件,在txt文件中,根据句号把文本分隔成一行一行文本,从而实现把pdf转换成doccano标注格式。
提供了两个文件转换功能:

  1. pdf转txt;
  2. txt转doccano的TextLine的文件格式;

下述是具体的函数说明:
trans_pdf_text: 实现把pdf转成txt文件,is_delete_page=True删除PDF的页码;

trans_folder_pdf2txt(prov, output_folder='pdf2txt'): 实现把prov文件夹下的所有pdf转成txt文件,存储到output_folder文件夹下;

cut_txt2sents(input_file, output_file, *args):
  使用split('。')把文本切分成列表,args使用filters.py中的过滤函数进行过滤。
主要使用get_length_filter

代码实现

filters.py的代码如下:

def contains_digit_filters(sentence):
    """
    判断句子中是否包含数字
    """
    for char in sentence:
        if char.isdigit():
            return True
    return False


def get_length_filter(bottom_len=8, top_len=1e3):
    """
        文本长度过滤器,返回一个过滤器,
        用于筛选出文本长度在bottom_len与top_len之间的句子
    """
    def _length_filter(text):
        if bottom_len <= len(text) <= top_len:
            return True
        return False

    return _length_filter


def catalog_filter(text):
    """
        过滤章节,识别到章节则返回False,删除掉
    :param text:
    :return:
    """
    text = text.strip()
    head = text[:5]
    if '第' == head[0]:
        if '章' in head or '节' in head or '篇' in head:
            return False
    return True


def title_filter(text):
    if len(text) <= 45:
        if '国民经济和社会发展' in text and '五年规划' in text:
            return False
    return True

过滤器说明:

get_length_filter(bottom_len=8, top_len=1e3):
  筛选长度在bottom_len与top_len之间的文本,bottom_len筛选掉长度太短的文本,top_len可筛选掉文本的目录。

下面是主要代码:

import os
import re
from filters import get_length_filter, title_filter

"""
pdf -> txt
txt -> doccano
"""


def delete_page_num(text):
    """
        删除页码
    :param text:
    :return:
    """
    page_nums = [
        r'\n- \d+ -( *?)\n',
        r'\n— \d+ —( *?)+\n',
        r'\n\d+( *?)\n',
        r'\nI+( *?)\n',
    ]

    patterns = [re.compile(pattern) for pattern in page_nums]
    for pattern in patterns:
        text = pattern.sub('', text)
    return text


def trans_pdf_text(input_file, output_file, is_delete_page=True):
    """
        把pdf文件转为txt,删除页码,保存到output_file
    :param input_file:
    :param output_file:
    :param is_delete_page:
    :return:
    """
    import fitz
    pdf_file = fitz.open(input_file)  # pdf_path是PDF文件的路径

    res = []
    for i in range(len(pdf_file)):
        page = pdf_file.load_page(i)
        res.append(page.get_text())

    text = ''.join(res)
    if is_delete_page:
        text = delete_page_num(text)
    with open(output_file, 'w') as f:
        f.write(text)


def trans_folder_pdf2txt(prov, output_folder='pdf2txt'):
    """
        把某目录下pdf文件转为txt,方便预览和手动修改
    :return:
    """
    filenames = list(filter(
        lambda x: x.endswith('.pdf'),
        os.listdir(prov)
    ))
    if not os.path.exists(p := os.path.join(output_folder, prov)):
        os.mkdir(p)

    for filename in filenames:
        filename = os.path.join(prov, filename)
        output_file = os.path.join(output_folder, filename.replace('.pdf', '.txt'))
        trans_pdf_text(
            filename,
            output_file
        )


def cut_txt2sents(input_file, output_file, *args):
    """
        这部分处理由pdf转的txt文件,再将txt文本按照句号。切分
        由于pdf转的txt文件,其文件内容很乱,需要进行一些处理
        * args: 过滤器
            针对句子的过滤器
    """
    # 删除  
    delete_list = [
        '\xa0', '\t', '\u3000',
        ' ', '', ' ', ' ', '​',
        '目\n录\n', '\n'
    ]

    if input_file.endswith('.txt'):
        with open(input_file, 'r', encoding='utf-8') as f:
            text = f.read()

        for char in delete_list:
            text = text.replace(char, '')

        text = text.replace(';', '。')
        text = text.replace(';', '。')

        ## 本来按照\n切分最好,但是pdf转txt后,其中包含很多的\n,所以无法使用\n提前切分
        # texts = text.split('\n')

        # for text in texts:
        #     data.extend(text.split('。'))
        data = text.split('。')
        # 过滤器
        for arg in args:
            data = filter(arg, data)

        with open(output_file, 'w') as f:
            f.write('\n'.join(data))


def trans_folder_txt2doccano(input_folder, output_folder, *filter_funcs):
    """
        把某目录下的txt文件转为doccano格式
        针对一整个文件夹内的文件,批量操作)
    :return:
    """
    filenames = list(filter(
        lambda x: x.endswith('.txt'),
        os.listdir(input_folder)
    ))
    if not os.path.exists(output_folder):
        os.mkdir(output_folder)
    for filename in filenames:
        cut_txt2sents(
            os.path.join(input_folder, filename),
            os.path.join(output_folder, filename),
            *filter_funcs
        )



    trans_folder_txt2doccano(
        os.path.join(pdf_txt_folder, prov),
        os.path.join('doccano', prov),
        get_length_filter(8, 200),
        title_filter
    )

    trans_folder_txt2doccano(
        prov, f'doccano/{prov}',
        get_length_filter(8, 200)
    )

代码运行结果

原始文件夹介绍:

湖北省: 存放原始文件,里面有一些pdf文件和txt文件;
pdf2txt: 存放pdf转txt的结果,若希望修改可以手动修改;
doccano: 最终的doccano TextLine 输入格式的文件;
在这里插入图片描述

pdf_txt_folder = 'pdf2txt'
prov = '湖北省'
trans_folder_pdf2txt(prov, pdf_txt_folder)

上述代码实现把湖北省文件夹下的pdf文件转成txt文件,并保存到pdf2txt文件夹下,程序运行结果如下:
在这里插入图片描述
pdf2txt/湖北省/鄂州市国民经济和社会发展第十四个五年规划和二〇三五年远景目标纲要.txt:
在pdf转txt后的文件中,包含有目录信息。
在这里插入图片描述

下述代码实现把pdf2txt/湖北省湖北省文件夹下的txt文件,转换为doccano输入格式,转换结果存储在doccano文件夹下

trans_folder_txt2doccano(
    os.path.join(pdf_txt_folder, prov),
    os.path.join('doccano', prov),
    get_length_filter(8, 200),
    title_filter
)

trans_folder_txt2doccano(
    prov, f'doccano/{prov}',
    get_length_filter(8, 200)
)

在这里插入图片描述
在txt转为doccano标注格式的过程中:
get_length_filter(8, 200):使用文件长度过滤器,只保留文本长度在8到200之间的文本;如下图所示,对比上图,利用长度过滤器删除掉了目录。
在这里插入图片描述

代码公开

  1. 链接: https://pan.baidu.com/s/1x_o70B9VJVg07VPxyMdubQ?pwd=ryku 提取码: ryku
     在百度网盘中,包含了湖北省文件夹下的pdf和txt文件。
  2. https://github.com/JieShenAI/csdn/tree/main/24/03/pdf_txt_doccano
      只有代码,不包括pdf和txt文件;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/477860.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AndroidStudio相关

1、AndroidStudio 改变.gradle .AndroidStudio 默认存储位置 1、AndroidStudio安装路径下 -> bin -> idea.properties 文件 将1和2的路径设置为自己的路径&#xff0c;将3和4取消注释或复制在下方 注意&#xff1a; idea.plugins.path 和 idea.log.path 必须去掉注释或重…

Etcd Raft 协议(进阶篇)

前言 在正式开始介绍 Raft 协议之间&#xff0c;我们有必要简单介绍一下其相关概念。在分布式系统中&#xff0c;一致性是比较常见的概念&#xff0c;所谓一致性指的是集群中的多个节点在状态上达成一致。在程序和操作系统不会崩溃、硬件不会损坏、服务器不会掉电、网络绝对可靠…

基于SpringBoot精品在线试题库系统

采用技术 基于SpringBoot精品在线试题库系统的设计与实现~ 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBootMyBatis 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 页面展示效果 系统功能结构图 学生管理 教师管理 专业管理 试卷管理 …

MySQL索引优化,MySQL索引失效的场景(超详细!)

目录 1.不遵循最左前缀原则 2.在索引列上使用&#xff08;计算&#xff0c;函数&#xff0c;or&#xff0c;类型转换&#xff09;&#xff0c;都是导致失效而导致全表扫描 3.范围查询 4.Select * 导致回表查询 5.不等空值还有or导致索引失效 6.like %写在左边导致索引失…

计算机408网课评测+资料分享

408当然有比较好的网课推荐&#xff0c;比如王道的视频课 现在大部分人备战408基本都用王道的讲义&#xff0c;然后再搭配王道408的课程来听&#xff0c;可以学的很好。 其中408视频课中&#xff0c;我认为讲的比较好的是数据结构&#xff0c;和操作系统&#xff0c;计算机组…

Talk|Mila研究所蒙特利尔大学刘圳:三维表征和三维网格的重建与生成

本期为TechBeat人工智能社区第580期线上Talk。 北京时间3月21日(周四)20:00&#xff0c;Mila研究所&蒙特利尔大学博士生—刘圳的Talk已经准时在TechBeat人工智能社区开播&#xff01; 他与大家分享的主题是: “三维表征和三维网格的重建与生成”&#xff0c;向大家系统地介…

基于Java的校园疫情防控管理系统(Vue.js+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 学生2.2 老师2.3 学校管理部门 三、系统展示四、核心代码4.1 新增健康情况上报4.2 查询健康咨询4.3 新增离返校申请4.4 查询防疫物资4.5 查询防控宣传数据 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBoot…

收割互联网大厂Offer面经

大家好&#xff0c;我是爱编程的喵喵。双985硕士毕业&#xff0c;现担任全栈工程师一职&#xff0c;热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。…

paddlepaddle框架构建数据集进行分类问题的时候,会发现数据集在构建的过程中不会构建标签(花分类)

问题描述 在做一个paddlepaddle项目的时候&#xff0c;需要使用神经网络对他进行分类&#xff0c;数据集的结构如下图&#xff0c;这时候我们可以使用常用dataset方法对数据集进行构建。 这时候我们就会发现一个问题&#xff0c;就是这个矿建不是构建标签&#xff0c;也就是说…

vue在页面使用Vue.prototype全局变量

文章目录 Vue.prototype 的基本概念使用 Vue.prototype 添加全局属性和方法添加全局属性添加全局方法 使用场景注意事项在模板中使用全局变量和方法方法1方法2方法3 Vue.prototype 的基本概念 Vue.prototype 是 Vue 实例的原型对象。在 JavaScript 中&#xff0c;每个构造函数…

【Java】Java程序员必备的一些流程图

一、spring的生命周期 Spring作为当前Java最流行、最强大的轻量级容器框架&#xff0c;了解熟悉spring的生命周期非常有必要&#xff1b; 首先容器启动后&#xff0c;对bean进行初始化按照bean的定义&#xff0c;注入属性检测该对象是否实现了xxxAware接口&#xff0c;并将相…

openlayers 入门教程(四):layers 篇

还是大剑师兰特&#xff1a;曾是美国某知名大学计算机专业研究生&#xff0c;现为航空航海领域高级前端工程师&#xff1b;CSDN知名博主&#xff0c;GIS领域优质创作者&#xff0c;深耕openlayers、leaflet、mapbox、cesium&#xff0c;canvas&#xff0c;webgl&#xff0c;ech…

20240316-2-协同过滤(collaborative filtering)

协同过滤(collaborative filtering) 直观解释 协同过滤是推荐算法中最常用的算法之一&#xff0c;它根据user与item的交互&#xff0c;发现item之间的相关性&#xff0c;或者发现user之间的相关性&#xff0c;进行推荐。比如你有位朋友看电影的爱好跟你类似&#xff0c;然后最…

轻松找回丢失数据EasyRecovery数据恢复软件让你无后顾之忧

轻松找回丢失数据&#xff0c;EasyRecovery数据恢复软件让你无后顾之忧&#xff0c;电脑数码行业必备工具&#xff0c;让你的数据安全有保障 &#xff01; 一、EasyRecovery数据恢复软件简介 在我们的日常生活中&#xff0c;无论是工作还是学习&#xff0c;都离不开电脑和数据…

26 OpenCV 查找边缘

文章目录 findContours 发现边缘drawContours 绘制边缘大致流程示例 findContours 发现边缘 cv::findContours( InputOutputArray binImg, // 输入图像&#xff0c;非0的像素被看成1,0的像素值保持不变&#xff0c;8-bitOutputArrayOfArrays contours,// 全部发现的轮廓对象…

Mac玩《幻兽帕鲁》为什么打不开D3DMetal?d3d错误怎么办 d3dxl error

我之前发了一篇讲Mac电脑玩Steam热门新游《幻兽帕鲁》的文章&#xff08;没看过的点这里&#xff09;&#xff0c;后来也看到很多朋友去尝试了&#xff0c;遇到了一些问题&#xff0c;无法进入《幻兽帕鲁》游戏&#xff0c;或者是玩的时候卡顿以及出现黑屏&#xff0c;通过我的…

Altium Designer中如何修改默认字体

Altium Designer软件安装后&#xff0c;原理图和PCB设计中的文本通常默认是Times New Roman。这是一种Windows系统安全字体&#xff0c;在很早之前的Windows系统中就已经默认安装了这个字体。这种字体对打印也比较友好&#xff0c;是一种很常见的印刷体。 但是这种字体对于习惯…

[Leetcode]930.和相同的二元子数组+992.K个不同整数的子数组 关键词:[子数组][滑窗]

文章目录 Leetcode 992方法一&#xff1a;滑窗右端每次1&#xff0c;左端来回滑动方法二&#xff1a;&#xff08;最多K种的子串数&#xff09; - &#xff08;最多K-1种的子串数&#xff09; 恰好K种 Leetcode 930方法一&#xff1a;&#xff08;最多和为goal的子串数&#x…

移动app测试的好处简析,有必要选择第三方软件测试机构吗?

移动app测试是指对移动应用程序进行全面、系统和深入的检查和验证&#xff0c;以确保其功能、性能和稳定性达到预期要求。在移动应用市场日益竞争激烈的今天&#xff0c;进行移动app测试是至关重要的。 一、移动app测试的好处&#xff1a;   1、具有确保应用质量的作用。通过…