美文网首页python学习Python基础学习
Python格式化解析不规则txt文本并转为dataframe

Python格式化解析不规则txt文本并转为dataframe

作者: __李大猫__ | 来源:发表于2018-04-18 15:17 被阅读0次

    很多时候我们拿到的文本文件都是格式不规范的,甚至是相当不规范的。。所以我们想要把不规范的文本文件变成规范的表格式,便于后续的模型训练和分析,在本篇文章中,主要的难点是从文本文件提取key-value的工作。

    Step-0:数据示例

    比如我们需要把如下数据中的key和value分别提取出来,并将相同key的值放在一列:

    qid=157238221 isAdopted=1 qTags= qTime=2010-06-03 19:47 giveScore=200 askerid=188349317 askerGrade=5 askerGoodRate=48 askerAnswerNumber=44 askerName=cribberbd aid=467956656 isBest=1 ahasComment=0 aTime=2010-06-04 16:54 aCon=参看:a href="http:baike.baidu.comview1678662.htm?fr=ala0_1_1" target="_blank"http:baike.baidu.comview1678662.htm?fr=ala0_1_1a answerid=169837710 answerName= answerCareField= answerGrade= answerGoodRate= answerNum= answerIsMaster= answerIsFamous= aid=467569408 isBest= ahasComment=0 aTime=2010-06-03 20:09 aCon= will always love you下载地址a href="http:mp3.baidu.comm?f=ms&rn=&tn=baidump3&ct=134217728&word=I+will+always+love+you&lm=-1" target="_blank"http:mp3.baidu.comm?f=ms&rn=&tn=baidump3&ct=134217728&word=I+will+always+love+you&lm=-1a answerid=129235439 answerName=唯念潇湘 answerCareField= answerGrade=5 answerGoodRate=40 answerNum=46 answerIsMaster=0 answerIsFamous=0 aid=467584335 isBest= ahasComment=0 aTime=2010-06-03 20:35 aCon=是i will always love you= = answerid=12422236 answerName=qizi86 answerCareField=电视" answerGrade=18 answerGoodRate=36 answerNum=13266 answerIsMaster=0 answerIsFamous=0 aid=467849272 isBest= ahasComment=0 aTime=2010-06-04 13:17 aCon=长风镖局》 answerid=194560318 answerName=水滴里的火花 answerCareField= answerGrade=2 answerGoodRate=19 answerNum=5 answerIsMaster=0 answerIsFamous=0 aid=470025197 isBest= ahasComment=0 aTime=2010-06-08 17:27 aCon=长风镖局》 answerid=192636431 answerName=346317740 answerCareField=校园生活 answerGrade=5 answerGoodRate=14 answerNum=17 answerIsMaster=0 answerIsFamous=0

    Step-1:数据载入:

    没什么可说的,直接with open,需要注意的是原始文档当中有特殊字符,因此需要加上忽略错误with open(filename,encoding='utf-8',errors='ignore') as f:

    另外由于原始文件特别大,为了避免内存直接爆掉,采用了循环逐行读取的f.readline()。

    Step-2:格式化:

    进入重头戏格式化,分析数据发现不同的keyvalue对是用空格分割的,但是许多内容中本身就有空格。。。坑爹啊这不是。。。看来直接用空格分割不靠谱。。。

    后来尝试了分割成list,用list组成dataframe,不过分完才发现,每条记录的key个数并不相同,所以这样做也会出问题。

    最后发现key、value之间是用=号分割的,因此采用正则来提取pattern,但是提取出来才发现,许多文本中也含有“=”这个特殊字符,做到这我已经想不出别的招来了= =,所以决定给“=”前后正则加上限制,只有大小写英文小写开头小写结束(分析不完整的参数key字典发现的规则)的才勉强算是正常的key,后面通过key传非空的比例来决定key的取舍,异常的key的值空率放在大样本上应该是接近百分百的。。

    最后话不多说,放代码吧:

    def load_data(filename,n):

        with open(filename,encoding='utf-8',errors='ignore') as f:

        #f=open('QACorpusData',encoding='utf-8',errors='ignore')

            #确定正则匹配模式

            pattern= re.compile(r'[a-z]{1,}[a-zA-Z]{1,}[a-z]{1,}=[^=]{0,} |[a-z]{1,}[a-zA-Z]{1,}[a-z]{1,}=[^=]{0,}')

            #循环文件中每一行

            kv_data_Q=[]

            kv_data_A=[]

            #for each_line in f:

            for k in range(0,n):

                #将Question和Answer分开分别建表

                each_line= f.readline()

                line=each_line.strip().split('\t')

                for i in range(0,len(line)):

                    ss=pattern.findall(line[i])

                    #print(ss)

                    #print(len(ss))

                    data=[]

                    #取出key-value并分割

                    for i in ss:

                        tmp=i.strip().split('=')

                        data.append(tmp)

                    #转换为dict类型

                    data_dict=dict(data)

                    #增加Q&A分类

                    if 'qid' in data_dict.keys():

                        #data_dict['type']='Q'

                        qid=data_dict['qid']

                        #append到Qusetion表

                        kv_data_Q.append(data_dict)

                    else:

                        data_dict['qid']=qid

                        #data_dict['type']='A'

                        kv_data_A.append(data_dict)

                        #append到Answer表

            df_Q=pd.DataFrame.from_dict(kv_data_Q)

            df_A=pd.DataFrame.from_dict(kv_data_A)

            return df_Q,df_A

        #f.close()

    Step-3:去除误识别:

    通过列的空值比例去除误识别,代码如下:

    #考察各列的空值个数

    def empty_count(df):

        n=len(df)#数据集记录数

        empty_cnt = pd.DataFrame(columns=['columns_name', 'normal', 'null','empty'])

        for c in df.columns:

            n_cnt=sum(df[c].isnull())#判断是否为NaN

            e_cnt=sum(df[c].apply(lambda x: True if x ==''  else False))#判断是否为空字符

            empty_cnt=empty_cnt.append({'columns_name':c,'normal':(n-n_cnt-e_cnt)/n,'null':n_cnt/n,'empty':e_cnt/n},ignore_index=True)

        return empty_cnt

        #print(empty_cnt)

    #删除异常的列   

    def del_cols(df):

        df_ec=empty_count(df)

        for col in df_ec[df_ec.null>=0.9].columns_name:

            df.drop(col,axis=1,inplace=True)

    for df_deal in [df_Q_Cheat,df_A_Cheat,df_Q_Normal,df_A_Normal]:

        del_cols(df_deal)

        print(df_deal,'check!')

    空值判断效果

    相关文章

      网友评论

        本文标题:Python格式化解析不规则txt文本并转为dataframe

        本文链接:https://www.haomeiwen.com/subject/megvkftx.html