APP下载

基于Python的工程图数据分析研究

2019-08-08陆承佳

电脑知识与技术 2019年18期
关键词:工程图数据分析

陆承佳

摘要:文章介绍了一个可用于自动分析、整理、导出工程图数据的Python脚本。该脚本利用Python标准模块os与第三方模块pdfplumber及xlwt,遍历目标路径下所有PDF格式文件,并提取每张图样中的关键信息,最终统一导入一个Excel工作簿,进而帮助工程师节省大量手动查找和记录所需的时间。

关键词:Python;工程图;PDF;Excel;数据分析

中图分类号:TP311     文献标识码:A

文章编号:1009-3044(2019)18-0266-03

Abstract: In this paper, a Python script is written to analyze, dispose and export data of engineering drawings automatically. It uses the standard module os and third-party modules pdfplumber & xlwt to traverse all PDF documents in the target path, then extract core data of each drawing and finally import them into an Excel workbook. This script can help engineers save much time spent in manual searching and recording.

Key words: Python; Engineering Drawing; PDF; Excel; Data Analysis

1 背景

无论是在产品设计、制造还是使用环节中,工程图都起到了至关重要的作用——设计者通过图样表达设计思想,制造者依据图样加工、检验、调试产品,使用者借助图样了解结构性能、运作参数等。

通过对比图样信息,工程师可以明确不同产品间的设计差异。但对于部分图面复杂的工程图,一些重要信息不易被直接找到。此外,当涉及图样较多时,工程师的核查分析工作将变得更为烦琐。

文章旨在使用Python程序设计语言编写一个自动化脚本,批量提取PDF工程图内的关键数据并写入Excel工作簿中,进而节省工程师手动查找和记录图样信息所需的时间。

2 开发环境简介

Python 是一門非常通用的高级语言[1]。自20世纪90年代初它诞生至今,Python凭借其简洁性、易读性以及可扩展性,已经成为最受欢迎的程序设计语言之一。

Python不仅自带有强大的标准库,可以执行系统管理、网络通信、文本读写等操作。而且,Python社区提供了大量第三方模块。它们功能极其丰富,覆盖科学计算、网站开发、图形系统等各种领域,并且大多成熟而稳定。

文章以Python 3.7内置的集成开发环境IDLE为平台编写程序,通过遍历某一文件夹内全部PDF格式图样,依次从中读取所需信息,再统一写入Excel工作簿内,最终实现工程图数据自动批量分析、整理、导出功能。

3 主要算法思路

现假定有30张PDF格式的电机图样,工程师需要从中抽取并整理所有电机的图号、供应商号、产地、电压、功率、转速等参数,并存储进一个Excel文档内。

工程图数据提取功能的Python脚本主函数如图1所示。

该功能的实现大致可分为两部分:PDF文档读取和Excel文档写入——分别对应示例代码中的PDF()与Excel()子函数。而在调用PDF()函数前,首先应指明文件所在目录路径,再创建一个列表(list)用以储存信息。接着,调用标准os模块的listdir()函数获取该文件夹的目录内容。

随后,对于其中全部PDF文档,逐一将它们的文件名与文件夹路径拼接,得到完整的文件路径并作为PDF()函数的实参。值得注意的是,虽然Python的列表不必像C/C++的数组一样预先定义元素个数,但为了便于按照paramName列表顺序存放所找到的数据以及优化程序算法,在定义paramValue列表的同时为其赋予了7个“空格”元素。然后,调用PDF()函数从电机图样获取参数并覆盖paramValue初始元素后,将该列表加入paramTable(一个包含列表的列表)中。

最后,调用Excel()函数将paramTable二维列表内所有元素(即30台电机的参数)写入一个Excel工作簿中。

4 PDF文档

4.1 第三方模块选取

目前,Python包管理工具pip已发布上千PDF文档相关项目。文章针对三个常用以读取PDF文本的模块,就它们是否适于提取工程图信息展开了对比研究:

首先,pdfminer3k作为PDFMiner 的Python 3移植版,既可通过命令行使用,又可整合到代码中[2]。但其只能直接采集表格内字符串,而无法保留信息之间的位置关系,不利于工程师准确找到目标数据。

其次,tabula-java是用以读取PDF表格数据的java库,而tabula-py作为其python 的简单封装亦仍依赖于java7/8。此外,实测表明tabula-py对表格进行处理时,会出现信息识别错误、无法区分不同表格等问题。

最后,pdfplumber是按页处理 PDF的模块,其不仅能获得页面的全部文字,而且提供了专门的方法用于处理表格。尽管在实际应用中,pdfplumber读取的数据依然存在一定瑕疵,但已明显优于pdfminer3k和tabula-py。

综上所述,文章最终选取了pdfplumber模块用以处理PDF工程图。

4.2 表格参数读取

使用pdfplumber模块分析PDF文档既可通过pdfplumber.Page类的.extract_text()方法将页面内所有字符对象采集到一个字符串中,亦可调用.extract_words方法获取每一个单词及其图面位置坐标并放入字典(dictionary)内。但鉴于电机参数大多被记录在表格内,文章最终采用.extract_tables()方法根据图面表格划分将数据放入不同字符串——对于不在任何表格内的信息如注释,同样可被导出。

使用.extract_tables()方法直接返回的是页面中全部表格的列表。该列表结构自上而下依次包括:单一表格(table)、行(row)以及格(cell)。因此,若要访问工程图内所有单元格必须经历4轮循环(算上主函数的文件遍历则为5层循环),详细代码如图2所示。

文章先通过字符串“DRAWING NO”(或“SHEET”)与“SITE”找到相关单元格,再调用split()函数将格内字符串分割成由若干子串组成的列表——由于未指定“分隔符”,split()将基于默认的空白字符:空格、换行符、制表符进行分割[1]。随后,判断每个列表是否为要求的信息——图号应为字母和数字结合,且首项为D或X的字符串;而产地只有四种情况。虽然,这种执行两次判断又增加了一次循环的算法对于一些简单的工程图显得有些冗余,但也极大地降低了从复杂图样提取错误数据的可能性。

在程序找到包含频率参数名(“HZ”或“FREQ”)的单元格后,将当前行(i)列(j)下第k行的单元格数据记入列表中——大部分情况下k等于1,即参数名之下一格就是其对应值。但对于如图5的表格,因为参数名行右端有两行,.extract_tables()方法在将表格转换成列表时,在参数名与参数值间也增加了一行空元素,所以k的值为2。其他电气参数的获取方式亦类似,文章便不再赘述了。

4.3 注释信息获取

因为注释同样会被.extract_tables()导出,并放入某一“单元格”字符串中,所以为获取注释内的信息,可采用和标题栏图号及产地相同的算法:先找到包含关键词的字符串,再分析并从中抽取目标数据。然而与标题栏表格不同的是,存放注释的字符串包含内容庞杂,除整段技术要求外,甚至还可能包括产品外形尺寸。因此,注释信息的判断、筛选逻辑亦必须更为“严苛”。

程序先从图样内找到包含供应商名或“供应商”(VENDOR)的单元格。其次,鉴于字符串中的句号并不是要求的内容,故将其替换为空格同时便于执行下一步操作。然后,调用split()函数将字符串分割成列表。最后,抽取出符合供应商号命名规则的列表元素。

5 Excel文档

5.1 第三方模块介绍

Python目前常用以处理Excel工作簿的模块包括xlrd,xlwt和xlutils。其中,xlrd只能读取xls;xlwt只能在新建xls后写入;xlutils能将xlrd.Book“复制”为xlwt.Workbook,从而获取现有xls数据并在其基础上进行写入,最终将新文件转存实现“修改”。

由于反復读写Excel文档会大幅降低程序运行效率,文章采用了先将全部收集到的信息存储在一个二维列表中,再将它们统一导入一个xls格式文件的算法,故只需引用xlwt模块执行单次写入操作即可。

5.2 数据写入

当完成文件夹目录下所有工程图的遍历并将数据存入paramTable二维列表后,主函数调用Excel()子函数开始将该列表的元素录入xls表格,具体代码如图8所示。

相比Excel软件本身,通过xlwt模块新建xls格式文件时,有必要在程序内“手动”设置一些参数。例如在创建“工作簿”(Workbook)的同时,文章指定了UTF-8 为“编码方式”(encoding)——UTF-8 编码简单快速、字符覆盖面广、出错率低,是Python、Linux 以及HTML 的标准文本编码格式[1]。其次,通过Workbook类的.add_sheet()方法新建了一个“工作表”(Worksheet)。

接着,构建两层循环并调用Worksheet类的.write()方法逐行、逐个将paramTable列表的子列及其元素写入表内。

最后,将该工作簿命名为“Parameter.xls”并保存在和工程图相同的目录下。

5.3 结果分析

最终,30张PDF电机图样的关键信息由Python脚本批量提取并写入Excel文档后,如图9所示。

然而,显然表中有不少单元格空缺了,甚至记入了错误的内容。下面便逐一对这些问题产生的原因展开分析:

1) 第5张图号为D159180P01的电机导出信息中缺失了产地,但其却是包含在实际PDF文档标题栏表格内的。将该图所有信息打印出后得知,是.extract_tables()方法误将同一单元格内的“TLR”分割为“TL”与“R”,并归入了不同字符串中。同理,第16张图D160171P01的频率参数也被错误地填入了“0/50”(原图中为“60/50”);

2) 第11、12张电机图样(D159878P01 & D159879P01)缺失了供应商号。经查实,原PDF电机图样内确实未包含该信息;

3) 倒数第5、6台电机(D965130P01 & D965128P01)的功率为小数。由于这两张图中的功率单位为“瓦”(W),而不是默认的“马力”(HP)。因此经过单位换算后,便得到了图9所示数据;

4) 最后4张工程图的供应商号和产地,甚至整张图纸信息都导出失败了。因为,.extract_tables()方法只能读取文本内容,而X13612048与X70660696的部分数据以图片形式显示在PDF文档内,而剩下两张工程图则整页均为图片。

综上所示,除了原图样信息不全与同类参数单位换算因素外,使用Python进行PDF文档数据分析的主要问题包括:1、表格内容划分错误;2、图片信息难以读取。对此,未来可能继续尝试其他方法或模块,并对图像识别技术展开研究。

6 结束语

文章介绍了基于Python编程语言的自动批量分析、整理、导出图样数据的功能。该功能利用Python标准模块os与第三方模块pdfplumber及xlwt,遍历目标路径下全部PDF格式文件,并提取每张工程图中的关键信息,最终统一导入一个Excel工作簿。

尽管,使用Python脚本采集的数据存在些许不足,依然有赖工程师手动完善,但同时该脚本也成功获取了大部分标准化图样的信息,从而帮助工程师省去了大量烦琐重复的工作。

最后,无论是Python语言本身,还是其第三方模块均仍在不断发展壮大。相信随着版本的更新迭代和功能的添加优化,Python还将被应用于更多大型、复杂的项目开发。

参考文献:

[1] Bill Lubanovic. Python语言及其应用[M]. 北京: 人民邮电出版社, 2016.

[2] Ryan Mitchell. Python网络数据采集[M]. 北京: 人民邮电出版社, 2016.

【通联编辑:谢媛媛】

猜你喜欢

工程图数据分析
“3+4”人才培养模式下本科阶段“工程图学”课程的优化设计
面向工程认证的机制专业工程图学(一)课程教学探索
分析三维CAD建模技术在工程图学中的应用
浅析大数据时代对企业营销模式的影响
项目式教学在工程图学课程中的探索与实践