Implementando multiprocesamiento para comparar un gran número de entradas en un diccionario de Python -- python campo con bioinformatics camp codereview Relacionados El problema

Implementing multiprocessing to compare large number of entries in a python dictionary


3
vote

problema

Español

Soy un principiante en la programación de Python, y estoy tratando de implementar multiprocesamiento al código que utilizo diariamente para mi tratamiento de datos. Esencialmente, el archivo de entrada tiene alrededor de 10 a 30 millones de lecturas donde cada lectura contiene 4 líneas de información. Hay dos elementos en la primera línea de cada cuatro líneas que estoy mirando. Primero busco si el primer elemento está en el diccionario. Si no, entonces agrego al diccionario, el primer elemento es la tecla, mientras que el segundo elemento es el valor. Pero si el primer elemento ya está en el diccionario, procedo a comparar si el segundo elemento está dentro de la lista de valores correspondiente a la clave. De manera similar, si el segundo elemento aún no está presente en la lista de valores, se agregará, de lo contrario, se considera un duplicado. Ahora, como puedes ver, el diccionario va a crecer a medida que se lean más líneas. Al final, solo será demasiado lento para un solo proceso para completar la tarea de manera eficiente. Para mis datos, a veces puede tomar una semana para terminar. Ahora tengo una comprensión simple de que si puedo implementar algo, se pueden utilizar tales procesos múltiples para comparar simultáneamente con mi diccionario, aceleraría las cosas significativamente (puedo reservar hasta 16 hilos de CPU dedicados a mi tarea). Pero, lamentablemente, el multiprocesamiento / multiproceso parece ser algo complicado. Agradecería que si alguien me puede dirigir un camino sobre cómo debería centrarse. A continuación se muestra el código que actualmente estoy usando:

  def sequence_mismatch (input_seq, input_dict, input_linker_length, j):     local_smm_list=[]     for stored in input_dict[input_seq[0:j:]]:         local_smm=0         for x in range(0, 7):             if input_seq[input_linker_length+j+x] != stored[x]:                 local_smm += 1         local_smm_list.append(local_smm)     if min(local_smm_list) == 0:         return 1     else:         return 0    # Main from datetime import datetime import itertools import sys try:     input_fastq = sys.argv[1]     linker_length_str = sys.argv[2]       output_file_name = sys.argv[3]     randomer_length = sys.argv[4] except:     print("Usage: ./PCRDupRm.py your_fastq.fastq linker_length output_file_name randomer_length")     sys.exit(1) startTime = datetime.now() linker_length=int(linker_length_str) i = int(randomer_length) output_file = open(output_file_name, 'w+') scanned_dict = {} with open (input_fastq, 'r') as seq_data:     for line1, line2, line3, line4 in itertools.izip_longest(*[seq_data]*4):         if line2[0:i:] not in scanned_dict:             scanned_dict.update({line2[0:i:]: [line2[(linker_length + i):(linker_length + i + 7):]]})             output_file.write(line1)             output_file.write(line2)             output_file.write(line3)             output_file.write(line4)         else:             comparison = sequence_mismatch (line2, scanned_dict, linker_length, i)             if comparison == 1:                 continue             else:                 scanned_dict[line2[0:i:]].extend([line2[(linker_length + i):(linker_length + i + 7):]])                 output_file.write(line1)                 output_file.write(line2)                 output_file.write(line3)                 output_file.write(line4)  output_file.close() print (datetime.now() - startTime)   
Original en ingles

I am a beginner in python programming, and I am trying to implement multiprocessing to the code I use daily for my data treatment. Essentially, the input file has around 10 - 30 millions of reads where each read contains 4 lines of information. There are two elements in the first line of every four lines that I am looking at. First I search if the first element is in the dictionary. If not, then I add to the dictionary the first element is the key while the second element is the value. But if the first element is already in the dictionary, I proceed to compare whether the second element is within the value list corresponding to the key. Similarly, if the second element is not already present in the list of values, it will be added, otherwise it is considered a duplicate. Now as you can see, the dictionary is going to grow as more lines are read. In the end, it will just be too slow for a single process to complete the task efficiently. For my data it sometimes can take a week to do finish. Now I have a simple understanding that if I can implement something such multiple processes can be utilized to simultaneously compare with my dictionary, it would speed things up significantly (I can reserve as many as 16 CPU threads dedicated to my task). But unfortunately, multiprocessing/multithreading seems to be a complicated thing. I would appreciate if someone can direct me a path on what should I be focusing on. Below is the code that I am currently using:

def sequence_mismatch (input_seq, input_dict, input_linker_length, j):     local_smm_list=[]     for stored in input_dict[input_seq[0:j:]]:         local_smm=0         for x in range(0, 7):             if input_seq[input_linker_length+j+x] != stored[x]:                 local_smm += 1         local_smm_list.append(local_smm)     if min(local_smm_list) == 0:         return 1     else:         return 0    # Main from datetime import datetime import itertools import sys try:     input_fastq = sys.argv[1]     linker_length_str = sys.argv[2]       output_file_name = sys.argv[3]     randomer_length = sys.argv[4] except:     print("Usage: ./PCRDupRm.py your_fastq.fastq linker_length output_file_name randomer_length")     sys.exit(1) startTime = datetime.now() linker_length=int(linker_length_str) i = int(randomer_length) output_file = open(output_file_name, 'w+') scanned_dict = {} with open (input_fastq, 'r') as seq_data:     for line1, line2, line3, line4 in itertools.izip_longest(*[seq_data]*4):         if line2[0:i:] not in scanned_dict:             scanned_dict.update({line2[0:i:]: [line2[(linker_length + i):(linker_length + i + 7):]]})             output_file.write(line1)             output_file.write(line2)             output_file.write(line3)             output_file.write(line4)         else:             comparison = sequence_mismatch (line2, scanned_dict, linker_length, i)             if comparison == 1:                 continue             else:                 scanned_dict[line2[0:i:]].extend([line2[(linker_length + i):(linker_length + i + 7):]])                 output_file.write(line1)                 output_file.write(line2)                 output_file.write(line3)                 output_file.write(line4)  output_file.close() print (datetime.now() - startTime) 
     
   
   

Lista de respuestas

1
 
vote
vote
La mejor respuesta
 

Simplemente descubrí que podría haber usado simplemente un diccionario anidado dentro de un diccionario en lugar de una lista anidada dentro de un diccionario. Ahora el script finaliza en minutos para cada muestra.

 

I just figured out that I could have simply used a dictionary nested inside a dictionary instead of a list nested inside a dictionary. Now the script finishes within minutes for each sample.

 
 

Relacionados problema

2  Una secuencia de errores  ( A sequence of mistakes ) 
Esta pregunta es parte de una serie que resuelve la Rosalind desafíos. Para la pregunta anterior en esta serie, consulte el código genético . El repositor...

10  Una clase de C ++ simple para empacar las cadenas de ADN  ( A simple c class for packing dna strings ) 
Introducción Tengo este pequeño programa C ++ que empaca una cadena de ADN sobre el alfabeto ACGT en un vector de bit, dos bits por carácter. Código ...

11  Cálculo de la probabilidad de conjunta de los eventos de N desde una secuencia de muestras de ocurrencias  ( Calculating the joint probability of n events from a sample sequence of occurren ) 
Estoy escribiendo un algoritmo para tomar una lista de muestras de secuencias de eventos, calcule las probabilidades de transición de 1 paso de las secuencias...

4  Vectorizamos la prueba exacta de Fisher  ( Vectorize fishers exact test ) 
Tengo dos marcos de datos / listas de datos, humanSplit 9988776655544331 , y son del formulario > ratSplit$Kidney_F_GSM1328570 ratGene ratRepli...

2  Tarea de procesamiento de datos para bioinformática  ( Data processing task for bioinformatics ) 
Hoy lanzé este programa C para manejar una tarea de procesamiento de datos bioinformáticos. El programa parece funcionar correctamente, pero quería saber si a...

7  Genomo de la cadena de clump para encontrar problema  ( Genome string clump finding problem ) 
Estoy tratando de resolver los problemas de bioinformática de un Curso Stepic . El problema planteado : encontrar grupos del mismo patrón dentro de un gen...

9  Analizando las etiquetas genéticas  ( Analyzing genetic tags ) 
He ido de ida y vuelta unas cuantas veces recientemente en mi estilo de codificación de Perl cuando se trata de las subrutinas del módulo. Si tiene un objeto ...

1  Salida de explosión en formato XML utilizando expresión regular  ( Parsing blast output in xml format using regular expression ) 
Hay muchas otras formas mejores de analizar la salida de explosión en formato .xml, pero tenía curiosidad por intentar usar la regex, incluso si no es tan sen...

2  Compara secuencia y encabezados de mapas en el archivo FASTA  ( Compare sequence maps headers in fasta file ) 
Este es el código PERL que compara la secuencia en FASTA FILE & AMP; Mapea el encabezado. Aunque el código está funcionando bien, todavía me gustaría hacerlo ...

4  Encontrar un motivo de proteína  ( Finding a protein motif ) 
He resuelto los bits carnos de este problema bioinformático , aunque un poco torpemente creo . En particular, me he metido a la manipulación de la informació...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos