Analyser tous les fichiers PubMed baseline en parallèle avec Python
Dans notre article précédent Comment analyser les données PubMed baseline avec Python nous avons étudié comment utiliser la bibliothèque pubmed_parser pour analyser les données medline PubMed avec Python.
Dans ce suivi, nous allons fournir un exemple de comment utiliser glob pour sélectionner tous les fichiers PubMed baseline dans un répertoire et utiliser concurrent.futures avec tqdm pour fournir un parallélisme de processus pratique mais facile à utiliser avec ProcessPoolExecutor et une barre de progression pour la ligne de commande.
D’abord, installez les prérequis avec
pip install git+git://github.com/titipata/pubmed_parser.git six numpy tqdmMaintenant téléchargez ce script, assurez-vous que des fichiers comme pubmed20n0002.xml.gz ou pubmed20n0004.xml.gz sont dans le même répertoire et exécutez-le :
#!/usr/bin/env python3
import pubmed_parser as pp
import glob
import os
from collections import Counter
import concurrent.futures
from tqdm import tqdm
# Source : https://techoverflow.net/2017/05/18/how-to-use-concurrent-futures-map-with-a-tqdm-progress-bar/
def tqdm_parallel_map(executor, fn, *iterables, **kwargs):
"""
Équivalent à executor.map(fn, *iterables),
mais affiche une barre de progression basée sur tqdm.
Ne supporte pas timeout ou chunksize car executor.submit est utilisé en interne
**kwargs est passé à tqdm.
"""
futures_list = []
for iterable in iterables:
futures_list += [executor.submit(fn, i) for i in iterable]
for f in tqdm(concurrent.futures.as_completed(futures_list), total=len(futures_list), **kwargs):
yield f.result()
def parse_and_process_file(filename):
"""
Cette fonction contient notre code d'analyse. Habituellement, vous ne modifieriez que cette fonction.
"""
# N'analyse pas les auteurs et références pour cet exemple, puisque nous n'en avons pas besoin
dat = pp.parse_medline_xml(filename, author_list=False, reference_list=False)
# Pour cet exemple, nous allons construire un ensemble de comptage de tous les IDs MeSH dans ce fichier
ctr = Counter()
for entry in dat:
terms = [term.partition(":")[0].strip() for term in entry["mesh_terms"].split(";")]
for term in terms:
ctr[term] += 1
return filename, ctr
if __name__ == "__main__":
# Trouve tous les fichiers pubmed dans le répertoire courant
all_filenames = glob.glob("pubmed*.xml.gz")
# Pour certaines charges de travail, vous voudrez peut-être utiliser un ThreadPoolExecutor,
# mais un ProcessPoolExecutor est un bon défaut
executor = concurrent.futures.ProcessPoolExecutor(os.cpu_count())
# Itère sur les résultats au fur et à mesure (l'ordre n'est pas le même que dans l'entrée !)
for filename, ctr in tqdm_parallel_map(executor, parse_and_process_file, all_filenames):
# NOTE : Si vous print() ici, cela peut interférer avec la barre de progression,
# mais nous l'acceptons ici puisque c'est juste un exemple
print(filename, ctr)Maintenant vous pouvez commencer à modifier l’exemple, notamment la fonction parse_and_process_file() pour faire le traitement que vous comptez faire.