python中的计算时间非常长

2024-09-29 23:27:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我在运行我的代码,它包含在查找平均值中。在大约600万行中CSV(ssm_雷斯尼克.txt),第一行是一个引用,第二行是另一个引用,第三个值是两个引用之间的“距离”。这种距离是由生物学标准随意定义的,对这个问题并不重要。大多数的参考文献都是。。。大多数参考,因此有超过600万行的巨大CSV。在另一个CSV中(所有_uniprot.txt文件)我有~3600个spot(第一列),每个都有一个或多个引用(第三列)。这些值与巨大的CSV相同。我需要将第二个文件的3600个引用与同一个文件中的所有其他3600-1引用进行比较。所有可能的组合,如果存在的话,都在第一个巨大的CSV文件(ssm)中_雷斯尼克.txt). 为了所有的位置_uniprot.txt文件,每个2个spot ref将作为对应引用的迭代器(在第三列中),并将迭代巨大的CSV文件,如果存在,则显示两个“VS”引用的值。在

我的代码有什么问题?好。。。每次迭代10秒,3600*3600*10=129.600.000秒=1500天(差不多5年)。这发生在我的核心i3中,但在mac上很好。下面是我的代码和每个文件的一部分。请告诉我。有没有代码设计缺陷?有什么方法可以减少计算时间?提前谢谢。。。在

import csv

spot_to_uniprot=open('all_spot_uniprot.txt', 'rbU')
STU=csv.reader(spot_to_uniprot, delimiter='\t')

uniprot_vs_uniprot=open('ssm_resnik.txt', 'rbU')
allVSall= csv.reader(uniprot_vs_uniprot, delimiter='\t')

recorder=open('tabela_final.csv', 'wb')
fout=csv.writer(recorder, delimiter='\t', quotechar='"')

dict_STU={} #dicionário 'spot to uniprot'
dict_corresp={} #for each pair of uniprot ref as key and as value
#a list of lists with the first list as one spot and the second list is the spot+1
dict_corresp_media={}##average of one spot to other
total_correspondencias_x_y=[]
_lista_spot=[]
lista_spot=[]
lista_temp=[]
lista_CSV=[]

for a in STU:
    _lista_spot.append(int(a[0]))
    if a[0] not in dict_STU.keys():
        dict_STU[a[0]]=[]
        dict_STU[a[0]].append(a[2])
    else:        
        dict_STU[a[0]].append(a[2])
n_spot=max(_lista_spot)

spot_to_uniprot.close()

##for aa in _lista_spot:
##    lista_spot.append(int(aa))
##lista_spot.sort()

for i in allVSall:
    lista_CSV.append(i)
tuple_CSV=tuple(lista_CSV)

uniprot_vs_uniprot.close()

for h in range(1, n_spot):
    for _h in range(h+1, n_spot+1):
        #print h, 'h da lista_spot'
        del total_correspondencias_x_y[:]
        total_correspondencias_x_y.append(dict_STU[str(h)])
        #print h, 'h'
        #print _h, '_h'
        #print __h, '__h'
        total_correspondencias_x_y.append(dict_STU[str(_h)])
        print total_correspondencias_x_y, 'total_corresp_x_y'

        for c1 in total_correspondencias_x_y[0]:
            if c1=='No Data':
                pass
            else:
                for c2 in total_correspondencias_x_y[1]:
                    if c2=='No Data':
                        pass
                    else:
                        #print c1, c2, 'c1 e c2'
                        for c3 in lista_CSV:
                            if c1 in c3[0]:
                                if c2 in c3[1]:
                                    lista_temp.append(c3[2])
                                    print lista_temp, 'lista_temp'

        elements=len(lista_temp)
        if len(lista_temp)==0:
            dict_corresp_media[str(h)+'_'+str(_h)]=0
        else:
            temp_d=0
            for d in lista_temp:
                temp_d +=float(d)
            media_spots=temp_d/elements
            dict_corresp_media[str(h)+'_'+str(_h)]=media_spots

        print dict_corresp_media[str(h)+'_'+str(_h)]
        lista_temp=[]

recorder.close()

这是我文件的一部分:

all_spot_uniprot.txt

^{pr2}$

ssm_resnik.txt

Q8DRQ4  O08397  1.0
Q8DRQ4  B5E568  1.0
Q8DRQ4  P59651  0.12077157944440875
Q8DRQ4  O06672  0.12077157944440875
Q8DRQ4  B5E569  0.12077157944440875
Q8DRQ4  Q8DRQ1  0.12077157944440875
Q8DRQ4  Q97TD0  0.12077157944440875
Q8DRQ4  B5E573  0.12077157944440875
Q8DRQ4  Q8DRP9  0.07139907404780385
Q8DRQ4  Q97TC5  0.07139907404780385
Q8DRQ4  B5E578  0.07139907404780385
Q8DRQ4  P59652  0.04789965413510797
Q8DRQ4  O69076  0.04789965413510797
Q8DRQ4  B5E580  0.04698170092888175
Q8DRQ4  Q8DRP6  0.12077157944440875
Q8DRQ4  P65888  0.05619465373456477
Q8DRQ4  P65887  0.05619465373456477
Q8DRQ4  B5E5G8  0.05619465373456477
Q8DRQ4  Q8DRP3  0.0115283466875553
Q8DRQ4  Q97TC0  0.0115283466875553
Q8DRQ4  B5E5G9  0.0115283466875553
Q8DRQ4  Q8DRP2  0.05619465373456477
Q8DRQ4  Q97TB9  0.05619465373456477
Q8DRQ4  B5E5H1  0.05619465373456477
Q8DRQ4  Q8DRP0  0.12077157944440875
Q8DRQ4  B5E5H3  0.12077157944440875
Q8DRQ4  Q8DNI4  0.12077157944440875
Q8DRQ4  Q8CWP0  0.12077157944440875
Q8DRQ4  Q97CV3  0.12077157944440875
Q8DRQ4  Q97P52  0.12077157944440875
O08397  Q97PH8  0.12077157944440875
O08397  P59200  0.10979991157849654
O08397  P59199  0.10979991157849654
O08397  B5E5I1  0.12077157944440875
O08397  Q8DRN5  0.047725405544042546
O08397  Q97TA8  0.047725405544042546
O08397  B5E5I4  0.047725405544042546
O08397  Q8DRN4  0.1555714706579846
O08397  Q97TA7  0.1555714706579846
O08397  B5E5I5  0.1555714706579846
O08397  Q97TA6  0.02938784938305615
O08397  Q8DRN2  0.02938784938305615
O08397  Q9F7T4  0.02938784938305615
O08397  P59653  0.04191624792292713
O08397  Q03727  0.04191624792292713
O08397  B5E5J1  0.045754049904644475
O08397  P59654  0.01167129073292015
O08397  P36498  0.01167129073292015
O08397  B5E5J2  0.0
O08397  Q8DRM7  0.05619465373456477
O08397  Q07296  0.05619465373456477
O08397  B5E5J3  0.05619465373456477
O08397  Q97TA3  0.05619465373456477
O08397  B5E5J5  0.05619465373456477
O08397  Q97T99  0.05619465373456477
O08397  Q8DRL9  0.05619465373456477
O08397  Q97T96  0.05619465373456477
O08397  B5E5K1  0.05619465373456477
O08397  Q97T95  0.05619465373456477
O08397  Q8DRL7  0.05619465373456477

Tags: 文件csvintxtfortempdicttotal
3条回答

600万行既可以保存在内存中,也可以保存在SQLite数据库中。把它放在那里,并利用查找优化提供:

with open('ssm_resnik.txt', 'rbU') as uniprot_vs_uniprot:
    reader = csv.reader(uniprot_vs_uniprot, delimiter='\t')
    allVSall = { tuple(r[:2]): float(r[2]) for r in reader }

现在,allVSall是一个提供O(1)查找的映射;这就省去了为每个生成的组合遍历整个600万行的开销。这是一批被保存的循环。在

在阅读all_spot_uniprot列表时,使用collections.defaultdict更容易:

^{pr2}$

这里不需要找到max值,只需列出这些键并将它们传递给itertools.permutations和{}函数来生成组合。在

下面的代码以更紧凑的形式复制您的操作,使用更少的列表,使用O(1)字典查找可以减少循环:

from itertools import permutations, product, ifilter

no_no_data = lambda v: v != 'No Data'
dict_corresp_media = {}

for a, b in permutations(dict_STU.iterkeys(), r=2):
    # retrieve the a and b lists of possible keys, for which we need to loop over their products
    # we filter each for the `No Data` keys
    aval, bval = ifilter(no_no_data, dict_STU[a]), ifilter(no_no_data, dict_STU[b])

    matches = [allVSall[c1, c2] for c1, c2 in product(aval, bval) if (c1, c2) in allVSall]
    dict_corresp_media['{}_{}'.format(a, b)] = sum(matches) / len(matches) if matches else 0

对于输入样本,它会在几秒钟内发出:

>>> pprint.pprint(dict_corresp_media)
{'10_1': 0,
 '10_2': 0,
 '10_3': 0,
 '10_4': 0,
 '10_5': 0,
 '10_6': 0,
 '10_7': 0,
 '10_8': 0,
 '10_9': 0,
 '1_10': 0.05619465373456477,
 '1_2': 0.12077157944440875,
 '1_3': 0,
 '1_4': 0.12077157944440875,
 '1_5': 0,
 '1_6': 0.07139907404780385,
 '1_7': 0.04759366973303256,
 '1_8': 0.12077157944440875,
 '1_9': 0,
 '2_1': 0,
 '2_10': 0,
 '2_3': 0,
 '2_4': 0,
 '2_5': 0,
 '2_6': 0,
 '2_7': 0,
 '2_8': 0,
 '2_9': 0,
 '3_1': 0,
 '3_10': 0,
 '3_2': 0,
 '3_4': 0,
 '3_5': 0,
 '3_6': 0,
 '3_7': 0,
 '3_8': 0,
 '3_9': 0,
 '4_1': 0,
 '4_10': 0,
 '4_2': 0,
 '4_3': 0,
 '4_5': 0,
 '4_6': 0,
 '4_7': 0,
 '4_8': 0,
 '4_9': 0,
 '5_1': 0,
 '5_10': 0,
 '5_2': 0,
 '5_3': 0,
 '5_4': 0,
 '5_6': 0,
 '5_7': 0,
 '5_8': 0,
 '5_9': 0,
 '6_1': 0,
 '6_10': 0,
 '6_2': 0,
 '6_3': 0,
 '6_4': 0,
 '6_5': 0,
 '6_7': 0,
 '6_8': 0,
 '6_9': 0,
 '7_1': 0,
 '7_10': 0,
 '7_2': 0,
 '7_3': 0,
 '7_4': 0,
 '7_5': 0,
 '7_6': 0,
 '7_8': 0,
 '7_9': 0,
 '8_1': 0,
 '8_10': 0,
 '8_2': 0,
 '8_3': 0,
 '8_4': 0,
 '8_5': 0,
 '8_6': 0,
 '8_7': 0,
 '8_9': 0,
 '9_1': 0,
 '9_10': 0,
 '9_2': 0,
 '9_3': 0,
 '9_4': 0,
 '9_5': 0,
 '9_6': 0,
 '9_7': 0,
 '9_8': 0}

当脚本花费很长时间时,我会:

python -m cProfile myscript.py

过了一段时间后我停止了脚本。并且输出将花费在任何函数和模块中的时间总和。数据越大,问题就在那里。在

在那里查找其他分析方法:How can you profile a python script?

除此之外,像评论建议你也可以考虑使用一个专用数据库。在

似乎你的程序的复杂性比问题的复杂度要高得多。使用类似cProfile或PyPy(或者甚至在C中重新实现)可以帮助您加快程序的某些部分,但不能解决基本问题,即嵌套的for循环。在

看看你能不能用更平和的方式重写算法。记住,这是Python和flat is better than nested。在

相关问题 更多 >

    热门问题