数据导入与预处理-第4章-数据获取Python读取PDF文档
- 1 PDF简介
- 1.1 pdf是什么
- 2 Python操作PDF
- 2.1 pdfplumber库
- 2.2 pdfplumber基本操作
- 2.2.1 打开pdf文档,并抽取文本
- 2.2.2 打开pdf文档,并抽取表格数据
- 2.2.3 打开pdf文档,抽取表格数据并过滤空值
- 2.3 pdfplumber操作教务数据pdf版本
- 2.3.1 查看数据
- 2.3.2 查看单个文件,并提取培养目标和学分学时比例说明
- 2.3.3提取学分学时数据并保存
- 2.3.4 完整代码如下:
1 PDF简介
1.1 pdf是什么
1、什么是pdf? PDF(Portable Document Foramt)是一种便捷式文本格式,由Adobe系统公司开发,其文件可以在任意操作系统中保持原有的文本格式。PDF文件中可以包含图片、文本、多媒体等多种形式的内容。
pdf也是文本格式之一,最大的特点是不能直接编辑,因此建议在编辑pdf文件时转换为可编辑的格式,或者在使用编辑工具直接创建pdf文件时简单地直接使用编辑器。
PDF 是Adobe Systems为与应用程序、操作系统和硬件无关地交换文件而开发的文件格式。 PDF文件基于PostScript语言的图像模型,保证了每台打印机的正确颜色和正确打印效果。 也就是说,PDF忠实地再现原稿的文字、颜色和图像。
3 .可移植的文档格式是电子文件格式
此文件格式与操作系统平台无关,即PDF文件在Windows、Unix和苹果公司的MAC操作系统中都是通用的。 这个特征成为在网上发行电子文件和进行数字化信息发布的理想文件形式。 越来越多的电子书、产品说明、公司文章、网络资料和电子邮件开始使用PDF格式的文档。
4 .提供网络信息发布的支持
Adobe设计了PDF文件格式,以支持跨平台多媒体集成的信息出版和分发,特别是web信息分发。 为了达到这个目的,PDF有很多其他电子文档格式无法比较的优点。 PDF文件格式可以将文本、字体、格式、颜色、与设备和分辨率无关的图形图像等封装在一个文件中。 该格式文件也可以包含超文本链接、声音、动画等电子信息,对应于特长文件,集成度和安全可靠性高。
二、发展趋势
1.pdf文件格式是1990年代初期开发的,可以包含文件的格式,作为内置图像的共享方法,而且可以跨平台操作, 完全不同的计算机平台上的收件人不一定在相关或并用的应用程序入当时与PDF竞争跨平台文件形式,DjVu (开发中)、Envoy、Common Ground Digital Paper、 在当时网络和HTML文本尚未兴起的头几年,PDF在桌面出版工作流技术中很受欢迎。
2.pdf以初始文档形式共享历史的接受程度很慢。 可以阅读和生成PDF格式的程序Adobe Acrobat不是免费产品。 早期版本的PDF也不支持外部链路,降低了互联网上的可用性。 与整个文本格式看起来巨大的PDF文件相比,在当时用调制解调器连接的时代,下载时间变长,而且用当年性能较低的电脑渲染PDF文件的过程也非常慢。
3 .从2.0版开始,Adobe开始免费分发PDF的阅读软件Acrobat Reader (现在称为Adobe Reader,制作软件依然称为Adobe Acrobat ),但旧格式依然支持。
4、到2008年,Adobe Systems的PDF参考了版本1.7,成为了ISO 32000:1:2008,从此PDF成为了正式的国际标准。 因此,现在的PDF更新版本开发(包括将来的PDF 2.0版本开发)由ISO的TC 171 SC 2 WG 8主导,但Adobe和其他相关项目的专家参加了。
2 Python操作PDF
2.1 pdfplumber库
Pandas中没有提供读取PDF文件的功能,这里需要借助第三方库pdfplumber读取PDF文件。 pdfplumber是一个完全由Python开发的PDF解析库,它不仅可以读取PDF文件中的文本数据,还可以读取PDF文件中的表格数据。若当前的环境中没有安装pdfplumber库,则需要先通过pip命令安装该库。
pip install pdfplumber
pdfplumber库主要提供了两个类PDF和Page,分别代表PDF文件和PDF文件中每一页实例。
- PDF类 PDF类对象对应一个PDF文件。使用pdfplumber库中的open()方法可以创建PDF类对象实例。
- Page类 Page类对象对应着PDF文件中每页的实例。Page类提供了多个从每页PDF中提取不同内容的方法。
使用pdfplumber库读取PDF文件的基本步骤:
2.2 pdfplumber基本操作
本操作基于一个 集合介绍.pdf 的文档,内容截图如下:
什么内容都不重要,大家在使用的使用,可以选择任意一篇pdf文档均可。
2.2.1 打开pdf文档,并抽取文本
with pdfplumber.open(‘集合介绍.pdf’) as pdf: 打开pdf文件 pdf.pages 抽取第0页 返回值为包含pdf每页实例的列表,pdf.pages[0]表示获取第0页的实例 .extract_text()表示针对页实例中提取文本数据
# pdf操作
import pdfplumber
with pdfplumber.open('集合介绍.pdf') as pdf:
# pdf.pages[0]表示获取第0页
# pdf.pages[0].extract_text()表示抽取第0页的所有文本数据
print(pdf.pages[0].extract_text())
输出为:
集合 Python 的集合(set)本身是可变类型,但 Python 要求放入集合中的元素必 须是不可变类型;集合类型与列表和元组的区别是:集合中的元素无序但必须唯 一。下面分创建集合、集合的常见操作和集合推导式三部分对集合进行介绍。 集合的常见操作 集合是可变的,集合中的元素可以动态增加或删除。Python 提供了一些内置 方法来操作集合,操作集合的常见方法如下表所示。 操作集合的常见方法 常见方法 说明 add(x) 向集合中添加元素x,x 已存在时不作处理 remove(x) 删除集合中的元素x,若x 不存在则抛出KeyError异常 discard(x) 删除集合中的元素x,若x 不存在不作处理 随机返回集合中的一个元素,同时删除该元素。若集合为空, pop() 抛出KeyError异常 clear() 清空集合 copy() 拷贝集合,返回值为集合 判断集合与集合T是否没有相同的元素,没有返回True, isdisjoint(T) 有则返回False
2.2.2 打开pdf文档,并抽取表格数据
with pdfplumber.open(‘集合介绍.pdf’) as pdf: 打开pdf文件 page.extract_tables()表示抽取每一页的表格数据
import pdfplumber
with pdfplumber.open('集合介绍.pdf') as pdf:
for page in pdf.pages: # 遍历每一页
for table in page.extract_tables(): # 抽取每一页的表格数据
print(table) # 输出
输出为:
[[‘’, ‘常见方法’, ‘’, ‘’, ‘说明’, ‘’], [‘add(x)’, None, None, ‘向集合中添加元素x,x 已存在时不作处理’, None, None], [‘remove(x)’, None, None, ‘删除集合中的元素x,若x 不存在则抛出KeyError异常’, None, None], [‘discard(x)’, None, None, ‘删除集合中的元素x,若x 不存在不作处理’, None, None], [‘pop()’, None, None, ‘随机返回集合中的一个元素,同时删除该元素。若集合为空,\n抛出KeyError异常’, None, None], [‘clear()’, None, None, ‘清空集合’, None, None], [‘copy()’, None, None, ‘拷贝集合,返回值为集合’, None, None], [‘isdisjoint(T)’, None, None, ‘判断集合与集合T是否没有相同的元素,没有返回True,\n有则返回False’, None, None]]
2.2.3 打开pdf文档,抽取表格数据并过滤空值
import re
with pdfplumber.open('集合介绍.pdf') as pdf:
for page in pdf.pages:
for table in page.extract_tables():
for data in table:
# 过滤数据中的None
clean_data = list(filter(None, data))
# 过滤数据中的换行符
print([re.sub("\n" ,'',value) for value in clean_data])
输出为:
[‘常见方法’, ‘说明’] [‘add(x)’, ‘向集合中添加元素x,x 已存在时不作处理’] [‘remove(x)’, ‘删除集合中的元素x,若x 不存在则抛出KeyError异常’] [‘discard(x)’, ‘删除集合中的元素x,若x 不存在不作处理’] [‘pop()’, ‘随机返回集合中的一个元素,同时删除该元素。若集合为空,抛出KeyError异常’] [‘clear()’, ‘清空集合’] [‘copy()’, ‘拷贝集合,返回值为集合’] [‘isdisjoint(T)’, ‘判断集合与集合T是否没有相同的元素,没有返回True,有则返回False’]
2.3 pdfplumber操作教务数据pdf版本
2.3.1 查看数据
对接 数据导入与预处理-第4章-数据获取python读取docx文档 ,在当时的项目中,文档除了doc和docx两种外,还有pdf的格式,对此,这里提供一个对pdf文件处理的方法: 查看单个文件 E:\vscode\reddemo\edudata\08\普本\01.pdf,内容如下:
01专业(本科)人才培养方案 一、专业名称:01 二、修业年限及毕业学分要求:基本学XXX求170学分。 三、授予学位:工学学士 四、培养目标: 本专业培养适应我国社会XX用型人才。 五、毕业要求: 1 工程知识:能够将XXX题。 指标1.1 能够XX问题; 指标1.2 能够XX模型; 指标1.3 能够XX方案; 2 问题分析:能够XX结论。 指标2.1 能够XX环节; 指标2.2 能够XX表达; 指标2.3 能够XX结论。 3 设计/开发解决方案:能够XX等因素。 指标3.1 掌握XX因素; 指标3.2 能够XX审核; 指标3.3 能够XX改进; 指标3.4 能XX因素。 4 研究:能够XX结论。 指标4.1 能够XX方案; 指标4.2 能够XX方案; 指标4.3 能够XX数据; 指标4.4 能够XX结论。 5 使用XX局限性。 指标5.1 了解XX性; 指标5.2 能够XX并运用于复杂工程问题; 指标5.3 能够XX其局限性。 6 工程与社会:能够XX的责任。 指标6.1 能够XX影响; 指标6.2 能够XX影响。 指标6.3 能够XX责任。 7 环境和XX的影响。 指标7.1 能够XX内涵; 指标7.2 能XX评价; 指标7.3 能够XX理念。 8 职业规范:具有XX责任。 指标8.1 能够XX国情; 指标8.2 能够XX责任。 9 个人和团队:能够XX角色。 指标9.1 能够胜任XX的任务; 指标9.2 能够与XX能力。 10 沟通:能够XX交流。 指标10.1 能够XX交流; 指标10.2 了解XX交流。 11 项目管理:理解XX应用。 指标11.1 掌握XX方法; 指标11.2 了解建XX问题; 指标11.3 能够XX控制。 12.终身学习:具有XX能力。 指标12.1 拥有健康的体魄,能够正确面对压力,快速适应社会的发展; 指标12.2 能够认识到自主学习和终身学习的重要性,拥有自主学习的能力,XX问题; 指标12.3 能够适应行业发展,具有不断跟踪和学习学科前沿的能力。 六、主干学科: (1)管XX程 (2)土XX程 七、主要课程: 工程XX审计等。 八、学分学时比例说明: 总学分为 170 学分,其中课内学分(含课内实践)为 129 学分,占总学分的 75.88%, 实践教学(含课内实践、集中实践、综合实践)学分为 61 学分,占总学分的 35.88%; 选修课学分为 16 学分,占总学分的 9.4%。通识教育平台学分为 48 学分,占总学分的 28.24%,学科基础教育平台学分为 35.5 学分,占总学分的 20.88%,专业教育平台学分 为 45.5 学分,占总学分的 26.76%。 课内总学时(含课内实践)为 2120 学时,其中选修课学时为 256 学时,占课内总 学时的 11.85%。通识教育平台学时为 832 学时,占课内总学时的 39.24%;学科基础教 育平台学时为 568 学时,占课内总学时的 26.8%,专业教育平台学时为 720 学时,占课 内总学时的 33.33%。 九、备注说明: --------。 十、附表 附表1:专业XX配表 附表2:专业XX示表 附表3:实践XX平台 附表4:通识XX平台 附表5:学科XX平台 附表6:专业XX平台 附表7:毕业XX矩阵 附表8:毕业XX矩阵
2.3.2 查看单个文件,并提取培养目标和学分学时比例说明
import re
filename = r'./edudata/08/普本/01.pdf'
def read_pdf(filename):
with pdfplumber.open(filename) as pdf:
pages_context = ""
pages_context_list = []
num = 0
for page in pdf.pages:
print(num)
if num > 4:
break
page_context = page.extract_text()
pages_context_list.append(page_context)
num += 1
pages_context = "".join(pages_context_list)
print("---------------")
# print(pages_context)
pages_context_replace = pages_context.replace('\n','')
pages_context_replace = re.sub(r'—.{1,2}\d.{1,2}—','',pages_context_replace)
# print(pages_context_replace)
print("---------------")
# 第4项的数据
re_4_start =re.compile(r".*?四.{1}培养目标(.*)五.{1}毕业要求")
re_4_end =re.compile("^五.{1}毕业要求:")
# 第8项的数据
re_8_start =re.compile(r".*?八.{1}学分学时比例说明(.*)九.{1}备注说明")
re_8_end =re.compile("^九.{1}备注说明")
matchObj_4 = re.match(re_4_start,pages_context_replace)
# print(matchObj_4.group(1))
matchObj_8 = re.match(re_8_start,pages_context_replace)
# print(matchObj_8.group(1))
str_4_part_all = ""
if matchObj_4:
print('----------')
print('matchObj_4.group() :',matchObj_4.group(1))
str_4_part_all = matchObj_4.group(1)
str_8_part_all = ""
if matchObj_8:
print('----------')
print('matchObj_8.group() :',matchObj_8.group(1))
str_8_part_all = matchObj_8.group(1)
part_all_dict_new = {}
part_all_dict_new[filename]={
"ID":filename,
"part_4":str_4_part_all,
"part_8":str_8_part_all,
}
return part_all_dict_new
filename,part_all_dict_new = filename,read_pdf(filename=filename)
df1 = pd.DataFrame(part_all_dict_new)
dfnew = df1.T
dfnew1 = dfnew.reset_index()
del dfnew1["index"]
dfnew1.to_excel("pdf_Data_T.xlsx",encoding="UTF-8")
dfnew1
输出为:
2.3.3提取学分学时数据并保存
定义一个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的数据如下:
dfnew1
输出为:
正则匹配输入到dfnew1_split中:
for i in range(dfnew1['ID'].count()): # 根据数据行数进行遍历
str1 = dfnew1['ID'][i] # 获取第i行的id 即文件全路径
# 定义正则表达式匹配数据
# 原始数据为
'''
总学分为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
输出为:
自此,完成匹配,如果把这段代码和 数据导入与预处理-第4章-数据获取python读取docx文档 的代码结合起来,只需要把代码合起来,完成如下:
2.3.4 完整代码如下:
from glob import glob
import re
from win32com import client as wc
# import docx
from docx import Document
import pandas as pd
import os
import numpy as np
import pdfplumber
def doc_read(file1):
word = wc.Dispatch("Word.Application")
doc = word.Documents.Open(file1)
doc.SaveAs(file1+"x",12)
doc.Close()
word.Quit()
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
for i in all_paragraphs:
start_paragraphs_num +=1
if(re.match(re_4_start,i.text)):
start_4_part = start_paragraphs_num
elif (re.match(re_4_end,i.text)):
end_4_part = start_paragraphs_num
elif(re.match(re_8_start,i.text)):
start_8_part = start_paragraphs_num
elif(re.match(re_8_end,i.text)):
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]
for i in part_4:
str_4_part_all = str_4_part_all+i.text
# 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
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
def read_pdf(file1):
with pdfplumber.open(file1) as pdf:
pages_context = ""
pages_context_list = []
num = 0
for page in pdf.pages:
print(num)
if num > 4:
break
page_context = page.extract_text()
pages_context_list.append(page_context)
num += 1
pages_context = "".join(pages_context_list)
print("---------------")
# print(pages_context)
pages_context_replace = pages_context.replace('\n','')
pages_context_replace = re.sub(r'—.{1,2}\d.{1,2}—','',pages_context_replace)
# — 4 —
# print(pages_context_replace)
print("---------------")
# content=str(content).replace('\n','t')
# 第4项的数据
re_4_start =re.compile(r".*?四.{1}培养目标(.*)五.{1}毕业要求")
re_4_end =re.compile("^五.{1}毕业要求:")
# 第8项的数据
re_8_start =re.compile(r".*?八.{1}学分学时比例说明(.*)九.{1}备注说明")
re_8_end =re.compile("^九.{1}备注说明")
matchObj_4 = re.match(re_4_start,pages_context_replace)
# print(matchObj_4.group(1))
matchObj_8 = re.match(re_8_start,pages_context_replace)
# print(matchObj_8.group(1))
str_4_part_all = ""
if matchObj_4:
print('----------')
print('matchObj_4.group() :',matchObj_4.group(1))
str_4_part_all = matchObj_4.group(1)
str_8_part_all = ""
if matchObj_8:
print('----------')
print('matchObj_8.group() :',matchObj_8.group(1))
str_8_part_all = matchObj_8.group(1)
part_all_dict_new = {}
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
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文件" + i)
fname,part_all_dict =read_pdf(str(i))
part_all_dict_new[fname] = part_all_dict[fname]
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)
df1 = pd.DataFrame(part_all_dict_new)
dfnew1 = df1.T
dfnew1 = dfnew1.reset_index()
del dfnew1["index"]
dfnew1.to_excel("firstData_T.xlsx",encoding="UTF-8")
dfnew1_split=pd.DataFrame(columns =['总学分','课内学分','课内学分占比','实践教学学分','实践教学占比','选修课学分',
'选修课学分占比','通识教育平台学分','通识教育平台学分占比','学科基础教育平台学分','学科基础教育平台学分占比',
'专业教育平台学分','专业教育平台学分占比','课内总学时','选修课学时','选修课学时占比','通识教育平台学时',
'通识教育平台学时占比','学科基础教育平台学时','学科基础教育平台学时占比','专业教育平台学时',
'专业教育平台学时占比','ID'])
dfnew1_split.set_index('ID',inplace=True)
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.to_excel("part8.xlsx")