Alle PubMed-Baseline-Dateien parallel mit Python parsen

English Deutsch

In unserem vorherigen Beitrag PubMed-Baseline-Daten mit Python parsen haben wir untersucht, wie man die pubmed_parser-Bibliothek verwendet, um PubMed-Medline-Daten mit Python zu parsen.

In diesem Folgebeitrag zeigen wir ein Beispiel, wie man glob verwendet, um alle PubMed-Baseline-Dateien in einem Verzeichnis auszuwählen, und concurrent.futures mit tqdm verwendet, um eine bequeme und einfach zu verwendende Prozess-Parallelität mit ProcessPoolExecutor und einer Fortschrittsanzeige für die Befehlszeile zu bieten.

Installieren Sie zuerst die Abhängigkeiten mit

install_pubmed_parser.sh
pip install git+git://github.com/titipata/pubmed_parser.git six numpy tqdm

Laden Sie nun dieses Skript herunter, stellen Sie sicher, dass einige Dateien wie pubmed20n0002.xml.gz oder pubmed20n0004.xml.gz im selben Verzeichnis sind, und führen Sie es aus:

parse_pubmed_parallel.py
#!/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):
    """
    Entspricht executor.map(fn, *iterables),
    zeigt aber eine tqdm-basierte Fortschrittsanzeige.

    Unterstützt kein timeout oder chunksize, da executor.submit intern verwendet wird

    **kwargs wird an tqdm übergeben.
    """
    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):
    """
    Diese Funktion enthält unseren Parsing-Code. Normalerweise ändern Sie nur diese Funktion.
    """
    # Autoren und Referenzen für dieses Beispiel nicht parsen, da wir sie nicht benötigen
    dat = pp.parse_medline_xml(filename, author_list=False, reference_list=False)

    # Für dieses Beispiel erstellen wir einen Satz mit der Anzahl aller MeSH-IDs in dieser Datei
    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__":
    # Alle PubMed-Dateien im aktuellen Verzeichnis finden
    all_filenames = glob.glob("pubmed*.xml.gz")
    # Für einige Workloads möchten Sie vielleicht einen ThreadPoolExecutor verwenden,
    # aber ein ProcessPoolExecutor ist ein guter Standard
    executor = concurrent.futures.ProcessPoolExecutor(os.cpu_count())
    # Ergebnisse iterieren, sobald sie eintreffen (die Reihenfolge entspricht nicht der Eingabe!)
    for filename, ctr in tqdm_parallel_map(executor, parse_and_process_file, all_filenames):
        # HINWEIS: Wenn Sie hier print() verwenden, könnte dies die Fortschrittsanzeige stören,
        # aber wir akzeptieren das hier, da es nur ein Beispiel ist
        print(filename, ctr)

Nun können Sie mit der Modifikation des Beispiels beginnen, insbesondere der Funktion parse_and_process_file(), um die gewünschte Verarbeitung durchzuführen.


Check out similar posts by category: Bioinformatics, Python