在正文中提取有实际意义的数字

在百度上抓取了大量的乡镇信息,但都是大段大段的文字,并无法直接用于结构化的数据分析,因此还需要在其中提取真正有用数据。这其中数字则是最为直观的数据。想要提取数字并不困难,用一个正则表达式比配一下就都出来了。但就这么一个光秃秃的数字是没有任何含义的,还需要知道这些数字要表达的是什么。以以下一段文字为例:

 

溶乡山多人少,人均稻田面积仅有0.6亩,农产品以水稻为主,杂粮有玉米、红薯、高粱、荞类等,经济作物有黄豆、菜油。林业用地43万亩,占总面积的76.4%,森林蓄积量达94万立方米,以林业的振兴发展拉动全乡经济发展是北溶乡党委政府历来坚定不移的发展思路,目前已申报国家级公益林18.7亩。近年来退耕还林面积1.3万亩,每年林农享受退耕还林国家补助近210万元。

 

这其中的想表达的数字有:

人均稻田面积0.6亩

林业用地43万亩

总面积的76.4%

森林蓄积量达94万立方米

已申报国家级公益林18.7亩

退耕还林面积1.3万亩

退耕还林国家补助近210万元

 

这里面可以看到想要表达一个数字含义还需要有名称,用来表示这个数字是干什么用的。可能的话还必须要有单位和量词,例如国家补助210,这里表示的是人数还是钱。

 

这里介绍一个不过的python插件jieba(结巴),不仅可以用来分词,还可以显示出当前分词的词性(名词,动词,量词...)。

 

插件安装很简单,可以直接pip install jieba,当前的版本是jieba-0.38。我用的是python2.7.10,对python3也是支持的。使用如下:

import jieba.posseg as pseg

if __name__ == '__main__':
    pass

    words=u"溶乡山多人少,人均稻田面积仅有0.6亩"
    
    cut_list=[]
    for cuts in pseg.cut(words):
        print cuts.word+"\t"+cuts.flag
        cut_list.append((cuts.word,cuts.flag))

结果:

溶乡    n
山    n
多    m
人    n
少    a
,    x
人均    j
稻田    n
面积    n
仅    d
有    v
0.6    m
亩    m

 

如此再回到之前的思路,可以对整段文字进行分词,然后用正则过滤出纯数字出来。针对于每个数字,向前找名词(一句里找不到名词就丢弃这个数字),向后找量词,这样就能够把整段文字有实际意义的数字给提取出来。

#!/usr/local/bin/python
# -*- coding: utf8 -*-

'''
Created on 2016年6月17日

@author: PaoloLiu
'''

import re
import jieba.posseg as pseg

if __name__ == '__main__':
    pass

    words=u"溶乡山多人少,人均稻田面积仅有0.6亩,农产品以水稻为主,杂粮有玉米、红薯、高粱、荞类等,经济作物有黄豆、菜油。林业用地43万亩,占总面积的76.4%,森林蓄积量达94万立方米,以林业的振兴发展拉动全乡经济发展是北溶乡党委政府历来坚定不移的发展思路,目前已申报国家级公益林18.7亩。近年来退耕还林面积1.3万亩,每年林农享受退耕还林国家补助近210万元。2005年起,境内大规模营造速生丰产林,“十一五”期间规划营造3800亩速生丰产林,15年后全乡林农创收可达1800万元。乡内碣滩茶在唐朝曾为贡品,自1981年后多次被评为湖南省优质茶,1989年被评为全国部优产品,1991年获国际茶文化节金奖。矿藏以金、银、铜、铁、铅、汞、重晶石最为丰富,其中重晶石储藏量在1000万吨以上,矿质优良,年产量8万吨,年销售收入1040万元,年上交税收83.2万元,年利润395万元。养殖条件好,有大量库汊水域,可成规模养鱼;草场面积较大,适合山羊、黄牛养殖。2005年全乡山羊达4525只,年底存栏3028只,出栏1497只。乡境经济发展将以林业、茶叶、重晶石开采加工、养殖业为四大支柱产业,带动境内经济全面发展,同时发展对外劳务输出。"
    
    cut_list=[]
    for cuts in pseg.cut(words):
#         print cuts.word+"\t"+cuts.flag
        cut_list.append((cuts.word,cuts.flag))
    
    for i in range (0,len(cut_list)):
        re_string="^(-?\\d+)(\\.\\d+)?$"
        
        if re.match(re_string,cut_list[i][0]):
            
            pass
            
            noun=""
            for j in range (i,-1,-1):
                
                if cut_list[j][1]=="x":
                    break
                
                if "n" in cut_list[j][1] or cut_list[j][1]=='j':
                    noun=cut_list[j][0]+noun
            if noun=="":
                continue
            
            number=cut_list[i][0]
            
            measure_word=""
            if cut_list[i+1]:
                if (cut_list[i+1][1]=="m") or (cut_list[i+1][1]=="x" and cut_list[i+1][0]=="%"):
#                     print cut_list[i+1][0]
                    measure_word=cut_list[i+1][0]
            
            print noun+number+measure_word
        

 

输出后的结果:

人均稻田面积0.6亩
林业用地43万亩
总面积76.4%
森林蓄积量94万立方米
申报公益林18.7亩
面积1.3万亩
林农国家210万元
规划营造3800亩
全乡林农1800万元
重晶石储藏量1000万吨
销售收入1040万元
税收83.2万元
利润395万元
全乡山羊4525
存栏3028

这样的数据再进行一定的取舍便就能够用于结构化的数据分析了

 

posted @ 2016-06-17 14:57  七块五  阅读(835)  评论(0编辑  收藏  举报