pandas处理txt格式医药说明书,并转换为CSV格式(含空行、换行)

接到一个述求,想把txt里面的药品说明书转换成csv格式,对应药品的属性为列名,属性的介绍作为values。分成两种方式实现,当然原数据是不一样的。

1.一个TXT文件中含有多个商品
原数据:
在这里插入图片描述
在这里插入图片描述
保存后的CSV格式数据:
在这里插入图片描述
在这里插入图片描述
直接上代码:

# -*- coding:utf-8 -*-
import pandas as pd
import re
import numpy as np
import os
import glob
from itertools import chain #展平列表
import numpy as np
from tqdm import tqdm
pd.set_option('display.max_columns', None)  #设置显示总行数

def split_item(df): 
    #分块商品,返回商品索引
    datas = list(chain.from_iterable(df.values.tolist()))
    items_index = []
    for i,data in  enumerate(datas):
        if data.find("个商品:") != -1:
            items_index.append(i)
    return   items_index,datas          

def lambda_name(x): 
    #获取药品属性
    if "【" in x:
        return str(x)[:str(x).find("】")].replace("【","")
        
def huanhang(it):
    #处理换行数据
    new_it = []
    #统计【开始的位置,去除最后一列
    str_dt = "".join(it[:-1])
    index = [i.start() for i in re.finditer('【', str_dt)]   
    for i in range(len(index)):
        if i+1 < len(index):
            new_it.append(str_dt[index[i]:index[i+1]])
        else:
            new_it.append(str_dt[index[i]:])
    new_it.append("【病情描述】"+it[-1])
    return new_it
          
data_path = glob.glob("*txt")
#pf = max_columns_dataframe(data_path)
pf = pd.DataFrame([{"药品名称":np.nan}])
pf = pf.dropna()
#添加数据
for n,file in enumerate(data_path):
    #df = pd.read_csv(file,encoding="gbk",names=['items'])   #读取含中括号时数据缺失
    df = pd.read_table(file,encoding="gbk",names=['items'])  #正常读取
    #columns = df[df.columns.tolist()[0]].apply(lambda x:str(x)[:str(x).find("】")].replace("【","")) #此处代码中存在一定缺陷,由于原数据中必须带有【】,负责查找不出来
    items_index,datas = split_item(df)  #返回商品索引
    data_bar = tqdm(list(range(len(items_index))))  
    for index in data_bar:        
        if index+1<len(items_index):
            if index==2448:
                print(131231231)
            it = datas[items_index[index]+1:items_index[index+1]]
            #换行数据处理
            it = huanhang(it)
            ddf = pd.DataFrame([it]).T  #单个药品说明书
            ddf.columns = [datas[items_index[index]]]    
            columns = ddf[ddf.columns.tolist()[0]].apply(lambda x:lambda_name(x))
            columns = columns.dropna()
            columns_name = columns.values.tolist()
            it_index = re.findall("\d+", ddf.columns.tolist()[0], flags=0)[0]  #获取商品ID
            data_bar.set_description(f'总共有{len(data_path)}个文件,正在处理{n+1}/{len(data_path)},{file}文件中第{index}个商品,商品id为{it_index}')
            dicts = dict.fromkeys(columns_name)
            tf = pd.DataFrame([dicts],index=[it_index])  #创建新datafrom
            for i,j in zip(columns_name,ddf.values.tolist()):
                if j[0].find(i) != -1:
                    if "】" in j[0]:
                        tf[i] = j[0].split(f"【{i}】")[-1]
                else:
                    tf[i] = np.nan
            pf = pd.concat([pf,tf])
pf.sort_index(inplace=True) #根据索引排序
pf.to_csv("药品说明书预处理.csv")

2 .每个TXT文件对应一个商品
原数据:
在这里插入图片描述保存后的CSV格式数据:
在这里插入图片描述
源码:

# -*- coding:utf-8 -*-
import pandas as pd
import re
import numpy as np
import os
import glob
pd.set_option('display.max_columns', None)  #设置显示总行数


def lambda_name(x): #获取药品属性
    if "【" in x:
        return str(x)[:str(x).find("】")].replace("【","")
    
    else:
        #给说明书中没有【】的加上【】
        name = list(x[:x.find(":")].strip())
        name.append("】")
        name.append(x[x.find(":"):])
        name.insert(0,"【")
        x = "".join(name)
        return str(x)[:str(x).find("】")].replace("【","")
    
def max_columns_dataframe(data_path):
    #返回药品说明书中最多的列
    num = []
    for i,path in enumerate(data_path): #
        df = pd.read_csv(path,encoding="utf-8")
        columns = df[df.columns.tolist()[0]].apply(lambda x:lambda_name(x)) 
        num.append(len(columns))
    file = data_path[num.index(max(num))] #找出列明最多的文件
    df = pd.read_csv(file,encoding="utf-8")
    columns = df[df.columns.tolist()[0]].apply(lambda x:lambda_name(x)) 
    columns_name = columns.values.tolist()
    index = re.findall("\d", df.columns.tolist()[0], flags=0)[0]  #获取商品ID
    dicts = dict.fromkeys(columns_name)
    pf = pd.DataFrame([dicts],index=[index])  #创建新datafrom    
    return pf.dropna()
   
data_path = glob.glob("*txt")
pf = max_columns_dataframe(data_path)
#添加数据
for file in data_path:
    df = pd.read_csv(file,encoding="utf-8")
    #columns = df[df.columns.tolist()[0]].apply(lambda x:str(x)[:str(x).find("】")].replace("【","")) #此处代码中存在一定缺陷,由于原数据中必须带有【】,负责查找不出来
    columns = df[df.columns.tolist()[0]].apply(lambda x:lambda_name(x))
    
    columns_name = columns.values.tolist()
    index = re.findall("\d", df.columns.tolist()[0], flags=0)[0]  #获取商品ID
    dicts = dict.fromkeys(columns_name)
    tf = pd.DataFrame([dicts],index=[index])  #创建新datafrom
    for i,j in zip(columns_name,df.values.tolist()):
        if j[0].find(i) != -1:
            if "】" in j[0]:
                tf[i] = j[0].split("】")[-1] 
            else:
                tf[i] = j[0].split(":")[-1]
        else:
            tf[i] = np.nan
    pf = pd.concat([pf,tf])
pf.sort_index(inplace=True) #根据索引排序
pf.to_csv("药品说明书预处理.csv")

遇到的问题总结:
1.有的药品说明书中没有【】号,因此在代码中加上【】,但是还存在缺陷,最好的是在爬虫的时候,将爬取的数据做一定的处理。
2.在多个商品在一个文件中,采用先将文件中的商品数的位置找出来,然后采用字符串的索引进行分块数据。
3.在成分一列中,存在换行,而pandas中读取的数据都是每一行,因此将数据中的换行先list成一句话,在进行处理。最好的方法是在爬虫的过程中进行处理。
4.使用pandas中读取 pd.read_csv(file,encoding=“gbk”,names=[‘items’]) 和pd.read_table(file,encoding=“gbk”,names=[‘items’]) ,前者在读取的数据中有[]时,读取的数据缺失,采用pd.read_table可以进行正常读取。

注:纸上得来终觉浅,绝知此事要躬行。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值