从模式化的文档中提取目标关键信息是一个重复性很高、劳动量很大的工作,而这类工作正是数据分析工具一展风采的地方。比如说从模式化的政府年终报告文档中提取诸如:GDP总量、GDP增长率、第一产业/第二产业/第三产业GDP…等。如下图所示:
如果提取几份文档,人工完全可以胜任;可是如果是提取全国地方政府的信息,那么工作量无疑是个天文数字。
然而,只要有效地利用好正则表达式(regex),这类的工作也是手到擒来。
本文将以部分政府年终报告文档为例,展示如何利用正则表达式高效地提取目标信息。
import os
import pandas as pd
import re
import pandas as pd
file_lists = []
for curdir,dirs,files in os.walk('./数据集/文本库/安徽省'): # 本项目的文件路径
for file in files:
if file.endswith('.txt'):
file = os.path.join(curdir,file)
file_lists.append(file)
print(len(file_lists))
该部分是项目的核心部分,主要是利用正则表达式精准地匹配目标字段,具体匹配的原则参见:http://www.runoob.com/regexp/regexp-syntax.html
patts1 = {'生产总值GDP':(
r'生产总值.*?(\d+.\d+)(\w+元).*?(增长|下降).*?(\d+.\d+\w*%)',(1,2)),
'GDP总量增长':(
r'生产总值.*?(\d+.\d+)(\w+元).*?((增长|下降).*?(\d+.\d*.*?%*))',(3,)),
'第一产业增加值':(
r'第一产业增加值.*?(\d+.\d+)(\w+元).*?(增长|下降).*?(\d+.\d+\w*(%|元))',(1,2)),
'第二产业增加值':(
r'第二产业增加值.*?(\d+.\d+)(\w+元).*?(增长|下降).*?(\d+.\d+\w*(%|元))',(1,2)),
'第三产业增加值':(
r'第三产业增加值.*?(\d+.\d+)(\w+元).*?(增长|下降).*?(\d+.\d+\w*(%|元))',(1,2)),
'人均GDP':(r'人均.*?(GDP|生产).*?(\d+).*?(\D*元).*?',(2,3)),
'户籍总人口':(r'(总人口|户籍人口).*?(\d+.\d+)(.*?人)',(2,3)),
'常住人口':(r'(常住人口).*?(\d+.\d+)(.*?人)',(2,3)),
'城镇住户人均可支配收入':(
r'(城镇).*?可支配收入.*?(\d+.\d+)(.*?元)',(2,3)),
'农村居民人均可支配收入':(
r'(农村).*?可支配收入.*?(\d+.\d+)(.*?元)',(2,3))
}
文档目标信息的提取需要利用大量的正则表达式分组操作,因此需要利用元组记录下分组的序号,然后遍历取出分组的目标信息。
citys_infos = {}
citys_errors = {}
print(len(file_lists))
for file in file_lists:
with open(file, 'r') as f:
s = f.read()
infos = {}
errors = {}
for key,val in patts1.items():
infos[key] = []
if len(val[1]) == 2:
try:
num = re.search(val[0],s).group(val[1][0])
char = re.search(val[0],s).group(val[1][1])
infos[key].append([num,char])
except Exception as e:
errors[key] = e
elif len(val[1]) == 1:
try:
char = re.search(val[0],s).group(val[1][0])
infos[key].append([char,None])
except Exception as e:
errors[key] = e
citys_infos[file] = infos
citys_errors[file] = errors
print(len(citys_infos))
print(len(citys_errors))
with open('数据.txt','w+',encoding='utf-8') as f:
for city in citys_infos:
# 获取分类文件夹的名称作为分类标签
label = city[city.rfind(
os.path.sep) + 1:].rsplit('.txt')[0]
for key,val in citys_infos[city].items():
data = label+'::'+key
for vl in val:
for v in vl:
if v:
data +='::'+v
f.write(data+'\n')
datas = pd.read_csv('数据.txt', sep='::',encoding='utf_8_sig',
engine='python',header=None)
datas.head()
datas.to_csv('安徽地方政府整合信息01.csv', mode='a',
encoding='utf_8_sig', index=False, sep=',')
再繁琐的数据只要存在一定的数据规律就可以被轻松拿下。而作为数据处理的利器,数量掌握正则表达式的匹配方法也很有必要!
参考网址:
http://www.runoob.com/regexp/regexp-syntax.html