2016-06-26 3 views
1

übertragen wurde Ich schrieb einen Code, der einige Operation auf einen Satz einer Datei und Elemente aus zwei Listen - keywords und keywords2. Es ist wie folgt -Drastische Reduzierung der Geschwindigkeit, wenn Listenbildung auf Funktion

import os 
keywords=['a','b'] 
keywords2=['c','d mvb'] 

def foo(sentence,k2): 

    gs_list=[]      ##### 
    for k in keywords:    #####  
     if k in sentence:   ##### 
      gs_list.append(k)  ##### 

    for k in gs_list: 
     if (k in sentence) and (k2 in sentence): 
      print 'a match' 
    return 4 

for path, dirs, files in os.walk(r'F:\M.Tech\for assigning cl\selected\random 100'): 
    for file in files: 
     sentences=open(file).readlines(); 
     for sentence in sentences: 
      if sentence.startswith('!series_title'):  
       for k2 in keywords2: 
        foo(sentence,k2) 

Ich habe den Teil des betreffenden Codes markiert. Dieses Stück (nennen wir es BETA) bildet im Wesentlichen eine Liste von Schlüsselwörtern, die in dem ausgewählten Satz sind. Daher müssen zukünftige Operationen nur mit diesen Schlüsselwörtern ausgeführt werden.

Dieser Code dauert ungefähr 47 Sekunden, um 100 Dateien auszuführen. Jetzt versuchte ich mir einen Weg zu überlegen, wie ich es beschleunigen könnte. Es gibt ~ 50 Elemente in keywords2. Also dachte ich, dass ich BETA 50 Mal laufen lasse, indem ich es innerhalb der Funktion func habe, wenn ich nur die Liste keywords und die sentence brauche. Ich mache schon im Haupt Code diese beiden haben so übertragen ich diesen Teil mit dem Hauptteil des Codes -

import os 
keywords=['a','b'] 
keywords2=['c','d mvb'] 

def foo(sentence,k2): 

    for k in gs_list: 
     if (k in sentence) and (k2 in sentence): 
      print 'a match' 
    return 4 

for path, dirs, files in os.walk(r'F:\M.Tech\for assigning cl\selected\random 100'): 
    for file in files: 
     sentences=open(file).readlines(); 
     for sentence in sentences: 
      if sentence.startswith('!series_title'): 

       gs_list=[]      ##### 
       for k in keywords:    #####  
        if k in sentence:   ##### 
         gs_list.append(k)  #####       

       for k2 in keywords2: 
        foo(sentence,k2) 

Mein Denken war, dass dies würde sicherstellen, dass diese Liste Prozess für jeden Satz nur einmal passiert, und nicht 50 mal wie vorher. Dies sollte definitiv die Geschwindigkeit des Codes erhöhen. Aber dieser Code dauerte 89 Sekunden, um durch die gleichen 100 Dateien zu gehen.

Ich kann nicht verstehen, warum dies mehr Zeit als der vorherige Code dauern kann. Irgendwelche Ideen?

Voll Code -

import os 
import re 
import time 
start_time = time.time() 
a = open('F:\M.Tech\patterns for gmk_down.txt','r').readlines() 
a1 = open('F:\M.Tech\patterns for gmk_up.txt','r').readlines() 
keywords2=a+a1 
ri2 = open(r'F:\M.Tech\for assigning cl\rules occurence\s\induced two.txt', 'w') 

keywords = open('F:\M.Tech\mouse_gs_small_simple_reduced.txt','r').readlines() # this has the new small GS 
keystripped = [k.rstrip().lower() for k in keywords] 
c=0 

def foo(s, gmk):  
    if gmk in s: # checking if gmk is in the line 
     l = re.split('\s|(?<!\d)[,.]|[,.](?!\d)|;|[()]|-', s) # split the line by comma, semicolon and space to check for gmks and gs. 
     filter(None, l)  # remove empty elements in the list 
     #gs_list = [k for k in keystripped if k in s] # <-------- PIECE IN QUESTION --------  
     for gs in gs_list: # gene symbols 

      gs1 = re.split('\s|(?<!\d)[,.]|[,.](?!\d)|;|-', gs) 
      gs1=filter(None, gs1) 
      gmk1 = re.split('\s|(?<!\d)[,.]|[,.](?!\d)|;|-', gmk) 
      gmk1=filter(None, gmk1) 
      if any(l[i:i+len(gs1)]==gs1 for i in xrange(len(l)-len(gs1)+1)) and (any(l[i:i+len(gmk1)]==gmk1 for i in xrange(len(l)-len(gmk1)+1))): # this ensures that both gs and gmk are in l, as a unit(i.e. and in order) otherwise it was detecting things like 'beta c' from beta cells 
       # UPTO THIS POINT WE HAVE ESTABLISHED THAT THE GMK AND GS ARE INDEED IN THE LINE      
       k1 = '_MKKEYWORD_1_' 
       k2 = '_SKEYWORD_2_' 
       #print gmk 
       text = re.sub(re.escape(gmk), k1, s, flags=re.I) # because of this replacement, we dont have the problem of counting r from behind etc. 

       text = re.sub(r'(\b%s\b)' % (re.escape(gs)), k2, text, flags=re.I) 
       lt = text.split()      
       d_idx = {k1:[], k2:[]} 
       for k,v in enumerate(lt): 
        if k1 in v: 
         d_idx[k1].append(k) 
        if k2 in v: 
         d_idx[k2].append(k) 
       distance = 8 
       data = [] 
       for idx1 in d_idx[k1]: 
        for idx2 in d_idx[k2]: 
         d = abs(idx1 - idx2) 
         if d<=distance: 
          data.append((d,idx1,idx2)) 

       data.sort(key=lambda x: x[0]) 
       for i in range (0, len(data)): 
        aq = data[i] 
        loq = min(aq[1], aq[2]) 
        hiq = max(aq[1], aq[2]) 
        brrq = lt[max(0, loq-6):hiq+6] 
        brq = " ".join(brrq)      

       if data:      
        cl(s, gmk, gs, gs_list, data) 


def cl(s1, gmk1, gs1, gs_list1, data1): # output will be the confidence level  
     if gmk1 == 'induced': 
      if re.search(r'(%s.*?-induced)' %gs1, br0, re.I|re.S): 
       ri2.write('good') 

    return 4   

c=0 

for path, dirs, files in os.walk(r'F:\M.Tech\for assigning cl\selected\random 100'): 
    for file in files: 
     sentences = open(os.path.join(path,file),'r').readlines();   
     print("--- %s seconds ---" % (time.time() - start_time)) 
     for s in sentences:    
      if s.startswith('!series_title'): 
       gs_list = [k for k in keystripped if k in s] #<------- PIECE IN QUESTION -------- 
       for k2 in keywords2: 
        k2 = k2.rstrip().lower() 
        foo(s, k2) 
ri2.close() 
print("--- %s seconds ---" % (time.time() - start_time)) 
+0

heidi schlug vor, dass mit der globalen Variablen arbeiten könnte mich nach unten verlangsamen, so ging ich 'gs_list' als Argument für 'foo', aber es dauerte noch 90 Sekunden! – user1993

+2

Anstatt sich darüber Gedanken zu machen, könntest du wahrscheinlich die Dinge beschleunigen, indem du die Sätze in Sätze umwandelst, die Mitgliedschaftstests _much_ schneller machen würden. Unabhängig davon würde ich auch vorschlagen, dass Sie das Modul [profile] (https://docs.python.org/2/library/profile.html#module-cProfile) verwenden, um zu sehen, wo Ihr Code die meiste Zeit verbraucht - anstatt zu raten. – martineau

+0

@martineau, ich bin neu in der Programmierung. Können Sie erweitern, was Sie meinen, indem Sie Sätze in Sätze umwandeln? – user1993

Antwort

1

Du nicht vorbei gs_list-foo. Es ist möglich, dass das Arbeiten mit globalen Variablen das Skript verlangsamt.

Erwägen Sie auch, BETA zu einem Listenverständnis zu machen. Dies sollte sein, was Sie brauchen:

gs_list = [k for k in keywords if k in sentence]

+0

versucht, das zu tun, dauerte es wieder 90 Sekunden. – user1993

+0

Bearbeitete meine Antwort mit einem anderen Vorschlag. – heidi

+0

Sie meinen also wie 'gs_list = [], gs_list = [k für k in Schlüsselwörtern wenn k in s], gs_list = [k.rstrip() für k in gs_list], gs_list = [k.lower() für k in gs_list] ' – user1993

Verwandte Themen