本文记录了在中医自动组方实习中对于中医数据预处理过程中使用过的python代码及遇到过的问题解决方法,代码没有什么深度只是日常操作,在此做个记录以便将来如果有问题再进行查找,如果有那位小伙伴在做类似的工作,请在博文下留言或者发邮件和我沟通交流([email protected])
以下为该项目的系列文章
工作记录
萤火虫算法
FCM模糊C聚类
爬虫及python代码
数据预处理
中医分类及python代码
数据预处理python代码
基于字典的最大正向匹配
基于欧式距离的方剂推荐
基于方剂相似性的方剂推荐
GitHub地址
import pandas as pd
import re
f = open('原始数据.csv','r')
f1 = open('分割后的药物名.txt','w',encoding='utf-8')
f = pd.read_csv(f)
yaowu = []
'''
对于药物的原始数据来说,因为很多方剂或者病例的药物组成中是药物剂量和炮制方法注意事项放在一起的
所有首先要对药物的剂量数据去掉(这一步的正则表达式很重要,一定要经过测试),然后在去掉炮制方法,得到单纯的药物信息
在药物组成信息中会有很多冗余的很杂的信息,在此要一并去掉
将得到的药物信息去重后保存起来以待后期处理
'''
for i in range(f.shape[0]):
a = f['药物组成'].loc[i]
a = re.sub(r'[\d半一二三四五六七八九十小中大][节两克片分枚个gml%寸钱斤对粒只付升铢株尺条盏秤滴厘杯双具斗颗匙头把至字合]',repl='',string=a)
a = re.sub(r'[节两克片分枚个gml%寸钱斤对粒只付升铢株尺条盏秤滴厘杯双具斗颗匙头把]半',repl='',string=a)
a = re.sub(r'[\d半一二三四五六七八九十小中大]?匙头[半]?',repl='',string=a)
a = re.sub(r'《.*》',repl='',string=a)
a = re.sub(r'一些|如鸡子大|鸡子大|茶碗|如小指大握|各等|不拘多少|不计多少|不以多少|如碗许大|两半|少许|适量|仁半|鸡子许|鸡子壳许|如鸡子|少许|若干|加倍|细末|小块|取汁斗',repl='',string=a)
a = re.sub(r'ko',repl='',string=a)
a = re.sub(r'[一二三四五六七八九十]+上末',repl='',string=a)
a = re.sub(r'-',repl='',string=a)
a = re.sub(r'或',repl='',string=a)
a = re.sub(r'[::]',repl='',string=a)
a = re.sub(r'?',repl='',string=a)
a = re.sub(r'[。.-\?]',repl='',string=a)
a = re.sub(r'(.*?)',string=a,repl='')
a = re.split(r'[,,、]',string=a)
yaowu.extend(a)
print(len(yaowu))
yaowu = set(yaowu)
print(len(yaowu))
yaowu = sorted(list(yaowu))
for i in yaowu :
if(len(i)>1):#通过分割之后出现了十几个一字词,但是很多一字词是因为数据不规范并没有实际意义,在此将其一并删除
# print(i)
f1.writelines([i,'\n'])
import pandas as pd
f1 =open('需要进行对应的药物数据.txt','r',encoding='utf-8')#需要进行对应的原始药物数据,可以认为所有数据都是药物的别名
f2 = open(r'药物字典.csv','r',encoding='utf-8')#药物字典,包括药物的标准名称、别名、性味、功效、主治、摘自
f3 = open('剩余无法被替换.txt','w',encoding='utf-8')#通过标准名称无法进行对应的药物
f4 = open('已经可以被替换的.txt','w',encoding='utf-8')
f2 = pd.read_csv(f2)
yaowushuju =[]
yaowubieming = []
for i in range(f2.shape[0]):
yaowushuju.append(f2['名称'].loc[i])
fangjishuju = []
for i in f1.readlines():
fangjishuju.append(i.strip())
wufatihuan = []
ketihuan = []
for i in fangjishuju:
flag = 0
tihuan = []
for j in yaowushuju:
if j in i :
flag = 1
tihuan.append(j)
if flag == 1:#因为是通过名称映射的,所有有可能会出现多个映射(比如“韭菜汁”中,可以对应韭菜、韭菜汁这两个药物标准名称,但是应该按照最长的进行映射)
a = []
for k in tihuan:
a.append(len(k))
aa = zip(tihuan,a)
b = sorted(aa,key= lambda x:x[1],reverse=True)
ketihuan.append(i)
f4.writelines([i,'\t',b[0][0],'\n'])
if flag == 0:
f3.writelines([i,'\n'])
wufatihuan.append(i)
print(len(fangjishuju))
print(len(wufatihuan))
print(len(ketihuan))
print(len(ketihuan)/len(fangjishuju))
import pandas as pd
import re
f2 = open(r'药物字典.csv','r',encoding='utf-8')
f3 = open('无法通过标准名称匹配的药物.txt.','r',encoding='utf-8')
f4 = open('别名均无法匹配.txt','w',encoding='utf-8')
f5 = open('别名匹配.txt','w',encoding='utf-8')
f6 = open('多个别名匹配待操作.txt','w',encoding='utf-8')
f2 = pd.read_csv(f2)
bieming = []
biaozhunming = []
for i in range(f2.shape[0]):#得到每个药物的别名和别名所对应的标准名称
a = f2['别名'].loc[i]
a = re.split(r'、',string=str(a))
b=[]
for j in range(len(a)):
b.append(a[j].strip())
bieming.append(b)
biaozhunming.append(f2['名称'].loc[i])
for i in f3.readlines():
i = i.strip()
yaowu = re.split(r'[\t、]',string=i)
daixuan = []
bufentihuan = []
wanquanpipei = []
for t in yaowu:
for j in range(len(bieming)):
flag = 0
for k in bieming[j]:
if k == t:#药物名和药物字典中的别名完全一样的
wanquanpipei.append(biaozhunming[j])
elif k in t:#有可能存在药物数据比较长,别名比较短,出现别名在药物描述之中,所以无法使用“==”,而是“in”进行字符串匹配
if k != '':
flag = 1
bufentihuan.append(biaozhunming[j])
if flag == 1:
daixuan.append(biaozhunming[j])
'''
对于不同的情况分别写到不同的文件之中
对于可以完全匹配分为匹配到一个别名、几个别名、无法完全匹配
对于无法完全匹配的药物分为字符串匹配到1一个别名、字符串匹配到几个别名、无法进行字符串匹配
'''
if len(wanquanpipei) == 1 :
f6.writelines([yaowu[0],'\t','、'.join(wanquanpipei),'\n'])
elif len(wanquanpipei) >1 :
f6.writelines([yaowu[0],'\t','、'.join(wanquanpipei),'\n'])
elif len(wanquanpipei) == 0:
if len(daixuan) == 1 :
if len(bufentihuan) > 0:
a = []
for t in bufentihuan:
a.append(len(t))
aa = zip(bufentihuan, a)
b = sorted(aa, key=lambda x: x[1], reverse=True)
# print(i,b[0][0])
f6.writelines([yaowu[0], '\t', b[0][0], '\n'])
elif len(daixuan) == 0:
print(yaowu[0], '在别名中无法找到对应词')
f4.writelines([yaowu[0], '\n'])
elif len(daixuan) > 1:
print(yaowu[0], '待操作')
# print(daixuan)
f6.writelines([yaowu[0], '\t', '、'.join(bufentihuan), '\n'])