如何提高np.where的性能(在line_profiler中花费98%的时间)

时间:2019-04-17 06:14:05

标签: python pandas dataframe search

我正在使用np.where搜索从大型数据帧中的文件读取的值,这需要98%的时间。该代码需要大约19个小时才能运行。

因此,此代码扫描包含约两百万条记录的2列的数据框,其中第一列包含数字,第二列包含文本。 现在的工作流程是我逐行读取另一个文件,然后在数据框中搜索“ alleleID”,并在匹配后从数据框中提取一些数据。我正在使用np.where代码。

res = np.where(df['alleleID'] == alist[0])

这行占line_profiler的约98%。那么,我该如何改善呢?

研究之后,我在建立索引后尝试了df.loc,但是发现的问题是,每次我搜索一次从文件中读取的一个alleleID,并且该变量都在变量(alist [0])中时,我无法传递该变量使用

进行搜索
res = df.loc(alist[0])

因为df.loc总是期望值而不是变量。

将感谢您对改善此程序性能的任何帮助。 谢谢。 完整的代码如下:

with open('C:/Data/DATA/ClinVar/temp.dat', 'r') as varFile:
    count = 0
    dat1 = []
    dat2 = []
    dat3 = []
    dat4 = []
    dat5 = []
    dat6 = []
    dat7 = []
    dat8 = []
    dat9 = []
    dat10 = []
    dat11 = []
    dat12 = []
    dat13 = []
    dat14 = []
    dat15 = []
    dat16 = []
    dat17 = []
    dat18 = []
    dat19 = []
    dat20 = []
    dat21 = []
    dat22 = []
    dat23 = []
    dat24 = []
    dat25 = []
    dat26 = []
    dat27 = []
    dat28 = []
    dat29 = []
    dat30 = []
    dat31 = []
    dat32 = []
    dat33 = []
    dat34 = []
    dat35 = []
    dat36 = []
    dat37 = []
    dat38 = []
    dat39 = []
    dat40 = []
    for line in varFile:
        alist = line.split('\t')
        count += 1
        print(alist[0], "-", count)
        if(alist[1] == 'single nucleotide variant'):
            hgvs = '-'
            aaChange = ''
            otherID = '-'
            otherID1 = '-'
            uniProt = ''
            uniProt_var = ''
            omim_list = ''
            if alist[2] and not alist[2].isspace():
                hgvs = alist[2].split(' ')
                i = 0
                for i in range(0,len(hgvs)):
                    if(hgvs[i][0] == "("):
                        aaChange = hgvs[i]
            else:
                hgvs = '-'
            otherID = alist[28].split(',')
            j = 0
            omim = ''
            uniprot = ''
            hgmd = ''
            hbvar_list = ''
            uni_list = ''
            hgmd_list = ''
            flag1 = 0
            flag2 = 0
            flag3 = 0
            flag4 = 0
            flag5 = 0
            indices1 = [i for i, elem in enumerate(otherID) if 'OMIM' in elem]
            for b in range(0, len(indices1)):
                omim = otherID[indices1[b]].split(':')
                flag2 += 1
                if(flag2 == 2):
                    omim_list = omim_list+','+omim[1]
                    #print("OMIM_list",omim_list)
                else:
                    omim_list = omim[1]
            indices2 = [i for i, elem in enumerate(otherID) if 'HGMD' in elem]
            for b in range(0, len(indices2)):
                hgmd = otherID[indices2[b]].split(':')
                flag3 += 1
                if(flag3 == 2):
                    hgmd_list = hgmd_list+','+hgmd[1]
                else:
                    hgmd_list = hgmd[1]
            indices3 = [i for i, elem in enumerate(otherID) if 'HBVAR' in elem]
            for b in range(0, len(indices3)):
                hbvar = otherID[indices3[b]].split(':')
                flag4 += 1
                if(flag4 == 2):
                    hbvar_list = hbvar_list+','+hbvar[1]
                else:
                    hbvar_list = hbvar[1]
            indices4 = [i for i, elem in enumerate(otherID) if 'UniProtKB' in elem]
            for b in range(0, len(indices4)):
                otherID1 = otherID[indices4[b]].split(':')
                flag5 += 1
                if(flag5 == 2):
                    uni_list = uni_list+','+otherID1[1]
                else:
                    uni_list = otherID1[1]
            AF_ESP = ''
            AF_EXAC = ''
            AF_TGP = ''
            res = np.where(df['alleleID'] == alist[0])
            if res[0].size != 0:
                res1 = df['info'][res[0][0]].split(';')
                indices5 = [i for i, elem in enumerate(res1) if 'AF_ESP' in elem]
                for b in range(0, len(indices5)):
                    res2 = res1[indices5[b]].split('=')
                    AF_ESP = res2[1]
                indices6 = [i for i, elem in enumerate(res1) if 'AF_EXAC' in elem]
                for b in range(0, len(indices6)):
                    res2 = res1[indices6[b]].split('=')
                    AF_EXAC = res2[1]
                indices7 = [i for i, elem in enumerate(res1) if 'AF_TGP' in elem]
                for b in range(0, len(indices7)):
                    res2 = res1[indices7[b]].split('=')
                    AF_TGP = res2[1]
            alist[30] = alist[30].rstrip('\n')

            dat1.append(alist[0])
            dat2.append(alist[1])
            dat3.append(alist[2])
            dat4.append(hgvs[0])
            dat5.append(aaChange)
            dat6.append(omim_list)
            dat7.append(uni_list)
            dat8.append(hgmd_list)
            dat9.append(hbvar_list)
            dat10.append(alist[3])
            dat11.append(alist[4])
            dat12.append(alist[5])
            dat13.append(alist[6])
            dat14.append(alist[7])
            dat15.append(alist[8])
            dat16.append(alist[9])
            dat17.append(alist[10])
            dat18.append(alist[11])
            dat19.append(alist[12])
            dat20.append(alist[13])
            dat21.append(alist[14])
            dat22.append(alist[15])
            dat23.append(alist[16])
            dat24.append(alist[17])
            dat25.append(alist[18])
            dat26.append(alist[19])
            dat27.append(alist[20])
            dat28.append(alist[21])
            dat29.append(alist[22])
            dat30.append(alist[23])
            dat31.append(alist[24])
            dat32.append(alist[25])
            dat33.append(alist[26])
            dat34.append(alist[27])
            dat35.append(alist[28])
            dat36.append(alist[29])
            dat37.append(alist[30])
            dat38.append(AF_ESP)
            dat39.append(AF_EXAC)
            dat40.append(AF_TGP)

# Creating DF from lists
df1 = []
df1 = pd.DataFrame(list(zip(dat1,dat2,dat3,dat4,dat5,dat6,dat7,dat8,dat9,dat10,dat11,dat12,dat13,dat14,dat15,dat16,dat17,dat18,dat19,dat20,dat21,dat22,dat23,dat24,dat25,dat26,dat27,dat28,dat29,dat30,dat31,dat32,dat33,dat34,dat35,dat36,dat37,dat38,dat39,dat40)), columns = ['alleleID','Type','Name','HGVSName','ProteinChange','OMIM','UniProt','HGMD','HBVAR','GeneID','GeneSymbol','HGNC_ID','ClinicalSignificance','ClinSigSimple','LastEvaluated',"RS# (dbSNP)",'nsv/esv (dbVar)','RCVaccession','PhenotypeIDS','PhenotypeList','Origin','OriginSimple','Assembly','ChromosomeAccession','Chromosome','Start','Stop','ReferenceAllele','AlternateAllele','Cytogenetic','ReviewStatus','NumberSubmitters','Guidelines','TestedInGTR','OtherIDs','SubmitterCategories','VariationID','AF_ESP','AF_EXAC','AF_TGP'])

1 个答案:

答案 0 :(得分:0)

好吧,我终于能够加快程序速度,只需将df.loc替换为np.where即可将其从19小时降低到5小时左右。 这是替换的代码:

df.loc[df['alleleID'].isin([a1[0]]), 'info'].values

有很多方法可以实现df.loc搜索/过滤器,但是有趣或令人惊讶的是,它们在Internet中都给出了以字符串形式传递值的示例(例如:“ 9879”或“托管”)。像这样,我必须在df中搜索15072。

df.loc[df['alleleID'] == '15072']

现在,这可以正常工作,但是我的问题是我正在从另一个文件读取值,所以我在变量中有值,所以我尝试如下操作:

var = 15072
df.loc[df['alleleID'] == var]

现在,此命令不起作用,由于某种原因给出了错误。

因此,我进行了更多探索,并做了一些修改,并使用了仅包含一个值的列表。如下:

list_a = []
list_a = ['15072']
df.loc[df['alleleID'].isin([list_a[0]]), 'info'].values

这最终奏效,并且从19小时改善到5小时。