如何使用 Python 并行解析所有 PubMed 基线文件

在我们的上一篇文章如何使用 Python 解析 PubMed 基线数据中,我们研究了如何使用 pubmed_parser 库用 Python 解析 PubMed medline 数据。

在此后续文章中,我们将提供一个示例,说明如何使用 glob 选择目录中的所有 PubMed 基线文件,并使用 concurrent.futurestqdm 通过 ProcessPoolExecutor 提供方便且易用的进程并行性和命令行进度条 UI。

首先,使用以下命令安装依赖

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

现在下载此脚本,确保一些类似 pubmed20n0002.xml.gzpubmed20n0004.xml.gz 的文件在同一目录中并运行它:

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

# 来源: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):
    """
    等同于 executor.map(fn, *iterables),
    但显示基于 tqdm 的进度条。

    不支持 timeout 或 chunksize,因为内部使用 executor.submit

    **kwargs 传递给 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):
    """
    此函数包含我们的解析代码。通常,你只需修改此函数。
    """
    # 对于此示例不解析作者和引用,因为我们不需要
    dat = pp.parse_medline_xml(filename, author_list=False, reference_list=False)

    # 对于此示例,我们将构建此文件中所有 MeSH ID 的计数集合
    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__":
    # 在当前目录中查找所有 pubmed 文件
    all_filenames = glob.glob("pubmed*.xml.gz")
    # 对于某些工作负载你可能想使用 ThreadPoolExecutor,
    # 但 ProcessPoolExecutor 是一个好的默认值
    executor = concurrent.futures.ProcessPoolExecutor(os.cpu_count())
    # 随着结果到来迭代(顺序与输入不同!)
    for filename, ctr in tqdm_parallel_map(executor, parse_and_process_file, all_filenames):
        # 注意:如果你在这里 print(),这可能会干扰进度条,
        # 但我们在这里接受它,因为这只是一个示例
        print(filename, ctr)

现在你可以开始修改示例,最值得注意的是 parse_and_process_file() 函数,以执行你打算做的任何处理。


Check out similar posts by category: Bioinformatics, Python