使用pandas对两张excel数据进行处理

本文使用到的技术点

  1. 使用pandas读取和写入exel;
  2. DataFrame类型转化为list
  3. difflib比较字符串的相似度
  4. python多线程
  5. 队列queue
import pandas as pd
import difflib
import queue
import threading
import time

time_start=time.time()
#a表读取
shanda_df=pd.read_excel('shanda.xlsx')
# data=df['ADH分泌过多综合征'].tolist()
# b表读取
hexin_df=pd.read_excel('hexin.xlsx')

hexin_data=[]
shanda_data=[]

# 遍历山大地纬dataframe插入list中,组成一个二元数组
for i in shanda_df.index.values:
    row_data=shanda_df.loc[i,['诊断ID','诊断名称']].tolist()
    shanda_data.append(row_data)

# 遍历核心dataframe插入list中,组成一个二元数组
for i in hexin_df.index.values:
    row_data=hexin_df.loc[i,['诊断ID','诊断名称']].tolist()
    hexin_data.append(row_data)

length=len(hexin_data)
sucs=[]
fail=[]
j=0

print('**************开始匹配****************')
# 多线程
def matchhx(arg):
    # 遍历核心list
    i=0
    for hexin in hexin_data:
        like = difflib.SequenceMatcher(None, arg[1], hexin[1]).quick_ratio()
        # 相似度大于0.7则匹配成功
        if like > 0.7:
            tem = []
            tem.append(arg[0])
            tem.append(arg[1])
            tem.append(hexin[0])
            tem.append(hexin[1])
            sucs.append(tem)
            break
        else:
            # 如果到最后一个还没有匹配到,则认为失败
            if i == length - 1:
                f = []
                f.append(arg[0])
                f.append(arg[1])
                fail.append(f)
        i += 1


que=queue.Queue(20)
# 遍历山大list
for shanda in shanda_data:
    # 创建线程执行函数
    t=threading.Thread(target=matchhx,args=(shanda,))
    t.start()
    que.put(t)
    # 计数器
    j += 1
    print('计数器', j)
    if que.full():
        for i in range(20):
            q=que.get()
            q.join()
        print('队列中的线程已经被执行完')






if que.qsize():
    for i in range(que.qsize()):
        q = que.get()
        q.join()
        print('剩余线程已经被执行完')

print('****************************匹配结束*********************************')
time_end=time.time()
print('****************************匹配时间:{shijian}*********************************'.format(shijian=time_end-time_start))

sucs_df=pd.DataFrame(sucs)
fail_df=pd.DataFrame(fail)


sucs_df.to_excel('success.xlsx',sheet_name='比较成功')
fail_df.to_excel('fail.xlsx',sheet_name='比较失败')


由于python的GIL锁特性,这种cpu复杂性用多线程解决并不适合,所以我重新写了一个多进程版的。

用到了进程池和正则表达式

import pandas as pd
import difflib
import queue
import threading
import time
import multiprocessing
import re

# 多进程
def matchhx(arg,reg1,reg2,reg3,hexin_data,length,j):
    # 遍历核心list
    i=0
    res=''
    res1=reg1.search(arg[1])
    res2 = reg2.search(arg[1])
    res3 = reg3.search(arg[1])
    if res1:
        res=res1.group(0)
    elif res2:
        res=res2.group(0)
    elif res3:
        res=res3.group(0)
    else:
        res=arg[1]
    keyword=''
    if len(res) <= 3:
        keyword=res
    elif 3<len(res)<=5:
        keyword=res[-3:]
    else:
        keyword=res[3:6]

    for hexin in hexin_data:

        if hexin[1].find(keyword)>=0:
            tem = []
            tem.append(arg[0])
            tem.append(arg[1])
            tem.append(hexin[0])
            tem.append(hexin[1])
            print('计数器', j)
            return tem
        else:
            # 如果到最后一个还没有匹配到,则认为失败
            if i == length - 1:
                f = []
                f.append(arg[0])
                f.append(arg[1])

                print('计数器', j)
                return f
        i += 1

if __name__ == "__main__":
    time_start = time.time()
    # 山大地纬码表读取
    shanda_df = pd.read_excel('fail.xlsx')
    # data=df['ADH分泌过多综合征'].tolist()
    # 核心码表读取
    hexin_df = pd.read_excel('hexin.xlsx')
    print('读取excel')
    hexin_data = []
    shanda_data = []

    # 遍历山大地纬dataframe插入list中,组成一个二元数组
    for i in shanda_df.index.values:
        row_data = shanda_df.loc[i, [0, 1]].tolist()
        shanda_data.append(row_data)

    # 遍历核心dataframe插入list中,组成一个二元数组
    for i in hexin_df.index.values:
        row_data = hexin_df.loc[i, ['诊断ID', '诊断名称']].tolist()
        hexin_data.append(row_data)

    length = len(hexin_data)
    sucs = []
    fail = []
    j = 0

    print('**************开始匹配****************')
    # 创建正则表达式对象
    regex1 = r'(?<=\)|\)|\]).+?(?=\(|\(|\[)'
    regex2 = r'.+?(?=\(|\(|\[)'
    regex3 = r'(?<=\)|\)|\]).+'

    reg1 = re.compile(regex1)
    reg2 = re.compile(regex2)
    reg3 = re.compile(regex3)
    # que=queue.Queue(10)
    # 创建进程池
    pool = multiprocessing.Pool(6)
    # 遍历山大list
    for shanda in shanda_data:
        # 计数器
        j += 1
        fail.append(pool.apply_async(matchhx,args=(shanda,reg1,reg2,reg3,hexin_data,length,j,)))
        # 创建线程执行函数
        # t=threading.Thread(target=matchhx,args=(shanda,))
        # t.start()
        # que.put(t)

        # if que.full():
        #     for i in range(10):
        #         q=que.get()
        #         q.join()
        #     print('队列中的线程已经被执行完')






    # if que.qsize():
    #     for i in range(que.qsize()):
    #         q = que.get()
    #         q.join()
    #     print('剩余线程已经被执行完')
    # 关闭进程池
    pool.close()
    # 等待进程执行完毕
    pool.join()
    print('********进程结束***********')
    for i in fail:
        sucs.append(i.get())
    print('****************************匹配结束*********************************')
    time_end=time.time()
    print('****************************匹配时间:{shijian}*********************************'.format(shijian=time_end-time_start))

    sucs_df=pd.DataFrame(sucs)
    # fail_df=pd.DataFrame(fail)


    sucs_df.to_excel('keyword_s.xlsx',sheet_name='比较成功')
    # fail_df.to_excel('keyword_f.xlsx',sheet_name='比较失败')


你可能感兴趣的:(案例)