首页 > 解决方案 > 正确实现 asyncio

问题描述

我正在尝试使用ensembl 基因组浏览器api 来获取一些基因组信息。挑战在于每个网络请求可能需要几秒钟,所以我一直在尝试使用asyncio等待这些网络请求的同时处理我拥有的数据。

这是我正在使用的示例输入 DataFrame:

import pandas as pd
df = pd.DataFrame({'Gene Name': {0: 'A1CF', 1: 'A1CF', 2: 'A1CF'},
 'Sample Name': {0: 'ATL045', 1: 'QC2-20-T2', 2: 'GHE0624'},
 'CDS Mutation': {0: 'c.234A>C', 1: 'c.492C>T', 2: 'c.490G>A'},
 'AA Mutation': {0: 'p.K78N', 1: 'p.V164V', 2: 'p.V164I'}})

目标是使用上面的Gene NameCDS Mutation信息df来获取其他一些基因组信息。

第一个方法旨在调用ensembl_calls将发出网络请求并返回一些解析输出的方法。理想情况下,解析后的输出会组合成一个类似于主 pandas 数据框的东西。

async def concurrent_location_info(df):
    import pandas as pd
    import asyncio

    full_df = pd.DataFrame()

    # iterate through DataFrame
    dfs = [asyncio.ensure_future(ensembl_calls(row)) for index, row in df.iterrows()]

    print(dfs)

在这种方法中,我试图发出我的网络请求并解析我得到的信息。

# this makes the network ensembl call asynchronously
async def ensembl_calls(row):
    new_df = {}

    try: # sometimes ensembl can't find what i'm looking for
        # this can take a while
        await info = Ensembl(row['Gene Name'], row['CDS Mutation']).info().split(',')

        # parse the output
        new_df['Gene'] = row['Gene Name']
        new_df['Chrom'] = info[0]
        new_df['Start'] = info[1]
        new_df['End'] = info[2]
        new_df['WT'] = info[3]
        new_df['Var'] = info[4]
        new_df['Sift_Index'] = info[5]
    except:
        pass

    return new_df # ideally somehow gets added to a master pd dataframe

我在正确的轨道上吗?有没有办法让它工作?

标签: pythonpython-asyncio

解决方案


尝试这个:

import pandas as pd
import asyncio


async def concurrent_location_info(df):
    # iterate through DataFrame
    tasks = [ensembl_calls(row) for _, row in df.iterrows()]
    df = pd.concat(asyncio.gather(*tasks))
    print(df)

并像这样修改第二个功能

info = await Ensembl(...)

这假设 Ensembl 有一个 async init方法,这是一种不常见的模式。


推荐阅读