数据导入与预处理-第4章-数据获取python读取docx文档(下)

简介: 数据导入与预处理-第4章-pandas数据获取docx文档1.python读取docx文档概述1.1 从Word文件获取数据1.2 python-docx库介绍1. Paragraph类2. Table类

读取单个文件,并获取培养目标和学分学时比例说明数据

filename1 = r"E:\vscode\reddemo\edudata\02\一本\02.docx"
# 可以存储到字典中了,但字典格式可以优化下
import numpy as np
# 创建一个接受匹配不成功的反馈记录 
# 第4项的数据  培养目标
re_4_start =re.compile("^四.{1}培养目标") # 匹配用 四.{1}培养目标 开头的文本
re_4_end =re.compile("^五.{1}毕业要求:")
# 第8项的数据 学分学时比例说明数据
re_8_start =re.compile("^八.{1}学分学时比例说明")
re_8_end =re.compile("^九.{1}备注说明")
# 抽取模式,不校验数据的准确性
def docx_read(file1):
    # 定义接受当前文档的part_4和part_8
    part_all_dict_new = {}
    # print("当前文件:====>",os.path.join("",file1))
    document = Document(os.path.join("",file1))
    # df=pd.DataFrame(columns =['总学分','课内学分','课内学分占比','实践教学学分','实践教学占比','选修课学分',
    #                      '选修课学分占比','通识教育平台学分','通识教育平台学分占比','学科基础教育平台学分','学科基础教育平台学分占比',
    #                     '专业教育平台学分','专业教育平台学分占比'])
    # 所有的段落,存放list
    all_paragraphs = document.paragraphs
    start_4_part = 0 # 培养目标 起始位置
    end_4_part = 0 # 培养目标 结束位置
    start_8_part = 0 # 学分学时比例说明 起始位置
    end_8_part = 0 # 学分学时比例说明 结束位置
    start_paragraphs_num = 0 # 定义段落初始值为0
    for i in all_paragraphs: # 便利所有的段落
        start_paragraphs_num +=1
        if(re.match(re_4_start,i.text)): #  如果该段以 四.{1}培养目标 为开头
            start_4_part = start_paragraphs_num # 将该段落的值设置为 培养目标 起始位置
        elif (re.match(re_4_end,i.text)): #  如果该段以 五.{1}毕业要求: 为开头
            end_4_part = start_paragraphs_num
        elif(re.match(re_8_start,i.text)): # 如果该段以 八.{1}学分学时比例说明 为开头
            start_8_part = start_paragraphs_num
        elif(re.match(re_8_end,i.text)): # 如果该段以 九.{1}备注说明 为开头
            end_8_part = start_paragraphs_num
        else:
            pass
    # 提取第4部分内容
    str_4_part_all = ""
    if start_4_part ==0 or end_4_part ==0 :
        print(file1,"的第4部分无法匹配")
    else:
        print("start_4_part   :   ",start_4_part)
        print("end_4_part   :   ",end_4_part)
        part_4 = all_paragraphs[start_4_part:end_4_part-1] # 通过list切片的方式获取 第4部分培养目标 的全部段落数据
        for  i in part_4:
            str_4_part_all = str_4_part_all+i.text # 把所有段落拼接到一个字符串变量str_4_part_all 中
        # print(str_4_part_all,"第4段的完成匹配")
    # 提取第8部分内容
    str_8_part_all = ""
    if start_8_part ==0 or end_8_part ==0 :
        print(file1,"的第8部分无法匹配")
    else:
        print("start_8_part   :   ",start_8_part)
        print("end_8_part   :   ",end_8_part)
        part_8 = all_paragraphs[start_8_part:end_8_part-1]
        for i in part_8:
            str_8_part_all = str_8_part_all+i.text
        # print(str_8_part_all,"的第8部分完成匹配")
    # print()
    # part_all_dict_new[file1+".id"] = file1
    # part_all_dict_new[file1+".part_4"] = str_4_part_all
    # part_all_dict_new[file1+".part_8"] = str_8_part_all
    # ID为文件名称 part_4为第4部分数据 part_8为第8部分数据
    part_all_dict_new[file1]={
        "ID":file1,
        "part_4":str_4_part_all,
        "part_8":str_8_part_all,
    }
    return file1,part_all_dict_new
print("*"*10)
file1,part_all_dict_new = docx_read(filename1)
print(file1)
print(part_all_dict_new)


运行,输出为:


**********

start_4_part : 8

end_4_part : 10

start_8_part : 63

end_8_part : 66

E:\vscode\reddemo\edudata\02\一本\02.docx

{‘E:\vscode\reddemo\edudata\02\一本\02.docx’: {‘ID’: ‘E:\vscode\reddemo\edudata\02\一本\02.docx’, ‘part_4’: ‘本专业培养适应我国社会主义现代化建设需要,德智体美劳全面发展,具有扎XX领域理论基础和专业知识,并熟练XXX人才。’, ‘part_8’: ‘总学分为170学分,其中课内学分(含课内实践)为119.5学分,占总学分的70.29%,实践教学(含课内实践、集中实践、综合实践)学分为60.5学分,占总学分的35.59%;选修课学分为44学分,占总学分的25.88%。通识教育平台学分为48学分,占总学分的28.24%,学科基础教育平台学分为29.5学分,占总学分的17.35%,专业教育平台学分为42学分,占总学分的24.71%。课内总学时(含课内实践)为1976学时,其中选修课学时为400学时,占课内总学时的20.24%。通识教育平台学时为832学时,占课内总学时的42.11%;学科基础教育平台学时为472学时,占课内总学时的23.89%,专业教育平台学时为672学时,占课内总学时的34.01%。’}}

2.2.4 获取指定目录下所有文档中的数据

通过遍历的方式,获取指定目录下的所有文件,并对doc文件另存为docx文件,提取docx中的相关数据,代码如下:

filedirs=r'E:\vscode\reddemo\edudata' # 所有文件存在的路径
# filenames = os.listdir("str1")
part_all_dict_new = {} # 存放所有匹配到的文件中的  四.{1}培养目标" 和八.{1}学分学时比例说明  数据
def contentExtract(str1): # 内容抽取函数 
    files = glob(str1 + '/*') # 匹配指定目录下的所有多层目录
    print(files) 
    for i in files:
        print("当前文件为:",i)
        if re.findall('.docx',i): # 如果当前文件为docx结尾
            fname,part_all_dict = docx_read(str(i)) # fname为文件名称ID,part_all_dict为该文件内容抽取后匹配到的数据
            # print(part_all_dict[fname])
            part_all_dict_new[fname] = part_all_dict[fname] # 将指定文件抽取后的数据 写入 part_all_dict_new字典, 用文件名称ID作为key
            # print("part_all_dict_new[fname]",part_all_dict_new[fname])
            # print(part_all_dict)
            # part_all_dict_new.update(part_all_dict)
        elif re.findall('.doc',i): # 如果当前文件以doc结尾
            doc_read(str(i)) # 将doc文件另存为docx
            fname,part_all_dict =docx_read(str(i) + 'x') # 读取另存后的docx文件
            part_all_dict_new[fname] = part_all_dict[fname]
            # print(part_all_dict)
            # part_all_dict_new.update(part_all_dict)
        elif re.findall('.pdf',i): # 如果当前文件以pdf结尾
            print("这是一个pdf文件")
        elif os.path.isdir(i):
            print("当前为目录:",i)
            contentExtract(str(i)) # 迭代 如果为目录
    # print("part_all_dict_new*******",part_all_dict_new)
    return part_all_dict_new
part_all_dict_new1 = contentExtract(filedirs)
part_all_dict_new1

输出为:


Output exceeds the size limit. Open the full output data in a text editor
[‘E:\vscode\reddemo\edudata\01’, ‘E:\vscode\reddemo\edudata\02’, ‘E:\vscode\reddemo\edudata\03’, ‘E:\vscode\reddemo\edudata\04’, ‘E:\vscode\reddemo\edudata\05’, ‘E:\vscode\reddemo\edudata\06’, ‘E:\vscode\reddemo\edudata\07’, ‘E:\vscode\reddemo\edudata\08’, ‘E:\vscode\reddemo\edudata\09’, ‘E:\vscode\reddemo\edudata\10’, ‘E:\vscode\reddemo\edudata\11’, ‘E:\vscode\reddemo\edudata\12’, ‘E:\vscode\reddemo\edudata\13’, ‘E:\vscode\reddemo\edudata\14’, ‘E:\vscode\reddemo\edudata\tree.txt’]
当前文件为: E:\vscode\reddemo\edudata\01
当前为目录: E:\vscode\reddemo\edudata\01
[‘E:\vscode\reddemo\edudata\01\一本’, ‘E:\vscode\reddemo\edudata\01\普本’]
当前文件为: E:\vscode\reddemo\edudata\01\一本
当前为目录: E:\vscode\reddemo\edudata\01\一本
[‘E:\vscode\reddemo\edudata\01\一本\01人才培养方案(2021版)2021年9月13日 - 02.docx’, ‘E:\vscode\reddemo\edudata\01\一本\02人才培养方案-2021版.doc’, ‘E:\vscode\reddemo\edudata\01\一本\02人才培养方案-2021版.docx’]
当前文件为: E:\vscode\reddemo\edudata\01\一本\01人才培养方案(2021版)2021年9月13日 - 02.docx
E:\vscode\reddemo\edudata\01\一本\01人才培养方案(2021版)2021年9月13日 - 02.docx 的第4部分无法匹配
E:\vscode\reddemo\edudata\01\一本\01人才培养方案(2021版)2021年9月13日 - 02.docx 的第8部分无法匹配
当前文件为: E:\vscode\reddemo\edudata\01\一本\02人才培养方案-2021版.doc
start_4_part : 9
end_4_part : 18
E:\vscode\reddemo\edudata\01\一本\02人才培养方案-2021版.docx 的第8部分无法匹配
当前文件为: E:\vscode\reddemo\edudata\01\一本\02人才培养方案-2021版.docx
start_4_part : 9
end_4_part : 18
E:\vscode\reddemo\edudata\01\一本\02人才培养方案-2021版.docx 的第8部分无法匹配
当前文件为: E:\vscode\reddemo\edudata\01\普本
当前为目录: E:\vscode\reddemo\edudata\01\普本
[‘E:\vscode\reddemo\edudata\01\普本\03.doc’, ‘E:\vscode\reddemo\edudata\01\普本\03.docx’, ‘E:\vscode\reddemo\edudata\01\普本\04.doc’, ‘E:\vscode\reddemo\edudata\01\普本\04.docx’, ‘E:\vscode\reddemo\edudata\01\普本\05.docx’]
当前文件为: E:\vscode\reddemo\edudata\01\普本\03.doc
start_4_part : 9
end_4_part : 11
start_8_part : 21
end_4_part : 9
start_8_part : 22
end_8_part : 25
当前文件为: E:\vscode\reddemo\edudata\tree.txt
Output exceeds the size limit. Open the full output data in a text editor
{‘E:\vscode\reddemo\edudata\01\一本\01人才培养方案(2021版)2021年9月13日 - 02.docx’: {‘ID’: ‘E:\vscode\reddemo\edudata\01\一本\01人才培养方案(2021版)2021年9月13日 - 02.docx’,
‘part_4’: ‘’,
‘part_8’: ‘’},
‘E:\vscode\reddemo\edudata\01\一本\02人才培养方案-2021版.docx’: {‘ID’: ‘E:\vscode\reddemo\edudata\01\一本\02人才培养方案-2021版.docx’,
‘part_4’: ‘培养XX并具有自主学习和适应发展的能力。’,
‘part_8’: ‘’},
‘E:\vscode\reddemo\edudata\01\普本\03.docx’: {‘ID’: ‘E:\vscode\reddemo\edudata\01\普本\03.docx’,
‘part_4’: ‘本专业XX应用技术型人才。’,
‘part_8’: ‘总学分为170学分,XX占课内总学时的26.2%。’},
‘E:\vscode\reddemo\edudata\01\普本\04.docx’: {‘ID’: ‘E:\vscode\reddemo\edudata\01\普本\04.docx’,
‘part_4’: ‘本专业培养适应XX应用技术型人才。’,
‘part_8’: ‘总学分为170学分,其中课内XX占总学时的21%。’},
‘E:\vscode\reddemo\edudata\01\普本\05.docx’: {‘ID’: ‘E:\vscode\reddemo\edudata\01\普本\05.docx’,
‘part_4’: ‘培养适应XX才。’,
‘part_8’: ‘总学分为170学分,XX占课内总学时的15.02%。’},
‘E:\vscode\reddemo\edudata\02\0224+工程造价双学位(更新后20211009).docx’: {‘ID’: ‘E:\vscode\reddemo\edudata\02\0224+工程造价双学位(更新后20211009).docx’,
‘part_4’: ‘’,
‘part_8’: ‘’},
‘E:\vscode\reddemo\edudata\02\一本\01.docx’: {‘ID’: ‘E:\vscode\reddemo\edudata\02\一本\01.docx’,
‘part_4’: ‘工程管理专业培养适应XX能力。’,
‘part_8’: ‘总学分为170学分,XX占课内总学时的31.20%。’},
‘E:\vscode\reddemo\edudata\02\一本\02.docx’: {‘ID’: ‘E:\vscode\reddemo\edudata\02\一本\02.docx’,
‘part_4’: ‘本专业培养XX人才。’,
‘part_8’: ‘总学分为170学分,XX占课内总学时的34.01%。’},
‘E:\vscode\reddemo\edudata\02\双学位\022.docx’: {‘ID’: ‘E:\vscode\reddemo\edudata\02\双学位\022.docx’,
‘part_4’: ‘法学双学位XX工作。’,
‘part_8’: ‘总学分为50学分,XX占课内总学时的37.5%。’},
‘E:\vscode\reddemo\edudata\14\第二学士学位\01.docx’: {‘ID’: ‘E:\vscode\reddemo\edudata\14\第二学士学位\01.docx’,
‘part_4’: ‘本专业XX人才。’,
‘part_8’: ‘总学分为80学分,XX占课内总学时的51.6%。’}}

以上会返回一个字典,包含了文件名,第4部分内容,第8部分内容

2.2.5 将结果字典保存到DataFrame中

通过字典转换为DataFrame格式。

df1 = pd.DataFrame(part_all_dict_new)
df1

转置DataFrame,并重置索引

dfnew = df1.T
dfnew1 = dfnew.reset_index()
dfnew1

输出为:


删除index列

del dfnew1["index"]
dfnew1
• 1
• 2

输出为:


把数据保存到excel中

dfnew1.to_excel("firstData_T.xlsx",encoding="UTF-8")
• 1

生成的如下所示:

2.2.6 提取学分学时数据并保存

定义一个DataFrame,用来获取part_8中的学分学时信息

dfnew1_split=pd.DataFrame(columns =['总学分','课内学分','课内学分占比','实践教学学分','实践教学占比','选修课学分',
                         '选修课学分占比','通识教育平台学分','通识教育平台学分占比','学科基础教育平台学分','学科基础教育平台学分占比',
                        '专业教育平台学分','专业教育平台学分占比','课内总学时','选修课学时','选修课学时占比','通识教育平台学时',
                          '通识教育平台学时占比','学科基础教育平台学时','学科基础教育平台学时占比','专业教育平台学时',
                          '专业教育平台学时占比','ID'])
print(dfnew1_split.shape)                        
dfnew1_split.set_index('ID',inplace=True)      
dfnew1_split  

输出为:


以上代码定义了一个空的DataFrame。

遍历dfnew1的每一行数据,并对part_8列数据进行正则表达式匹配,获取学时学分数据。

dfnew1的数据如下:


代码如下:

for i in range(dfnew1['ID'].count()): # 根据数据行数进行遍历
    str1 = dfnew1['ID'][i] # 获取第i行的id 即文件全路径
    str1 = str1[26:] # 切片操作
    str1 = str1.replace('.docx','') # 替换掉docx
    # 定义正则表达式匹配数据
    # 原始数据为
    '''
    总学分为173学分,其中课内学分(含课内实践)为134学分,占总学分的77.5%,
    实践教学(含课内实践、集中实践、综合实践)学分为60.5学分,占总学分的35%;
    选修课学分为21学分,占总学分的12.1%。
    通识教育平台学分为48学分,占总学分的27.7%,
    学科基础教育平台学分为44学分,占总学分的25.4%,专业教育平台学分为42学分,占总学分的24.3%。
    课内总学时(含课内实践)为2208学时,其中选修课学时为336学时,占课内总学时的15.2%。
    通识教育平台学时为832学时,占课内总学时的37.7%;
    学科基础教育平台学时为704学时,占课内总学时的31.9%,
    专业教育平台学时为672学时,占课内总学时的30.4%。
    '''
    reg = '总学分.*课内学分.*实践教学.*选修课.*通识教育平台.*学科基础教育.*专业教育平台.*课内总学时.*选修课.*通识教育平台.*学科基础教育.*专业教育平台.*'
    if len(re.findall(reg,str(dfnew1['part_8'][i])))!=0:
        q=re.findall(r'[0-9]+\.?[0-9]*',str(dfnew1['part_8'][i]))
        # q的值为list类型,值为 '170 129 75.88 73.5 43.24 23 13.53 48 28.24 26 15.29 55 32.35 2128 368 17.29 832 39.10 416 19.55 880 41.35'
        # print(len(q))
        # print(q)
        dfnew1_split.loc[str1]=q
    else:
        dfnew1_split.loc[str1]='' 
dfnew1_split  

保存数据到excel

dfnew1_split.to_excel("Course_Credit.xlsx",encoding="UTF-8")
• 1

保存后的数据如下:

相关文章
|
1月前
|
数据采集 数据可视化 数据挖掘
利用Python自动化处理Excel数据:从基础到进阶####
本文旨在为读者提供一个全面的指南,通过Python编程语言实现Excel数据的自动化处理。无论你是初学者还是有经验的开发者,本文都将帮助你掌握Pandas和openpyxl这两个强大的库,从而提升数据处理的效率和准确性。我们将从环境设置开始,逐步深入到数据读取、清洗、分析和可视化等各个环节,最终实现一个实际的自动化项目案例。 ####
113 10
|
12天前
|
数据采集 Web App开发 监控
Python爬虫:爱奇艺榜单数据的实时监控
Python爬虫:爱奇艺榜单数据的实时监控
|
1月前
|
数据采集 分布式计算 大数据
构建高效的数据管道:使用Python进行ETL任务
在数据驱动的世界中,高效地处理和移动数据是至关重要的。本文将引导你通过一个实际的Python ETL(提取、转换、加载)项目,从概念到实现。我们将探索如何设计一个灵活且可扩展的数据管道,确保数据的准确性和完整性。无论你是数据工程师、分析师还是任何对数据处理感兴趣的人,这篇文章都将成为你工具箱中的宝贵资源。
|
2月前
|
传感器 物联网 开发者
使用Python读取串行设备的温度数据
本文介绍了如何使用Python通过串行接口(如UART、RS-232或RS-485)读取温度传感器的数据。详细步骤包括硬件连接、安装`pyserial`库、配置串行端口、发送请求及解析响应等。适合嵌入式系统和物联网应用开发者参考。
64 3
|
2月前
|
图形学 Python
SciPy 空间数据2
凸包(Convex Hull)是计算几何中的概念,指包含给定点集的所有凸集的交集。可以通过 `ConvexHull()` 方法创建凸包。示例代码展示了如何使用 `scipy` 库和 `matplotlib` 绘制给定点集的凸包。
38 1
|
2月前
|
数据采集 JavaScript 程序员
探索CSDN博客数据:使用Python爬虫技术
本文介绍了如何利用Python的requests和pyquery库爬取CSDN博客数据,包括环境准备、代码解析及注意事项,适合初学者学习。
97 0
|
2月前
|
数据采集 存储 分布式计算
超酷炫Python技术:交通数据的多维度分析
超酷炫Python技术:交通数据的多维度分析
|
1月前
|
人工智能 数据可视化 数据挖掘
探索Python编程:从基础到高级
在这篇文章中,我们将一起深入探索Python编程的世界。无论你是初学者还是有经验的程序员,都可以从中获得新的知识和技能。我们将从Python的基础语法开始,然后逐步过渡到更复杂的主题,如面向对象编程、异常处理和模块使用。最后,我们将通过一些实际的代码示例,来展示如何应用这些知识解决实际问题。让我们一起开启Python编程的旅程吧!
|
1月前
|
存储 数据采集 人工智能
Python编程入门:从零基础到实战应用
本文是一篇面向初学者的Python编程教程,旨在帮助读者从零开始学习Python编程语言。文章首先介绍了Python的基本概念和特点,然后通过一个简单的例子展示了如何编写Python代码。接下来,文章详细介绍了Python的数据类型、变量、运算符、控制结构、函数等基本语法知识。最后,文章通过一个实战项目——制作一个简单的计算器程序,帮助读者巩固所学知识并提高编程技能。
|
21天前
|
Unix Linux 程序员
[oeasy]python053_学编程为什么从hello_world_开始
视频介绍了“Hello World”程序的由来及其在编程中的重要性。从贝尔实验室诞生的Unix系统和C语言说起,讲述了“Hello World”作为经典示例的起源和流传过程。文章还探讨了C语言对其他编程语言的影响,以及它在系统编程中的地位。最后总结了“Hello World”、print、小括号和双引号等编程概念的来源。
105 80