将异步函数应用于 pandas 数据帧的最快方法

Ром*_*тев 11 python dataframe pandas python-asyncio

pandas dataframe 中有一种apply方法允许应用一些同步功能,例如:

import numpy as np
import pandas as pd

def fun(x):
    return x * 2

df = pd.DataFrame(np.arange(10), columns=['old'])

df['new'] = df['old'].apply(fun)
Run Code Online (Sandbox Code Playgroud)

fun2如果必须应用异步函数,执行类似操作的最快方法是什么:

import asyncio
import numpy as np
import pandas as pd

async def fun2(x):
    return x * 2

async def main():
    df = pd.DataFrame(np.arange(10), columns=['old'])
    df['new'] = 0    
    for i in range(len(df)):
        df['new'].iloc[i] = await fun2(df['old'].iloc[i])
    print(df)

asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)

Hen*_*ker 14

完成后使用asyncio.gather并覆盖整个列。

import asyncio

import numpy as np
import pandas as pd


async def fun2(x):
    return x * 2


async def main():
    df = pd.DataFrame(np.arange(10), columns=['old'])
    df['new'] = await asyncio.gather(*(fun2(v) for v in df['old']))
    print(df)


asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)

这样做会将列中的每个值传递给异步函数,这意味着所有列值将同时运行(这比在循环中顺序等待每个函数结果要快得多)。

注意:保证保留列顺序,asyncio.gather并且在所有等待任务成功完成之前不会解析该列。

结果输出数据帧:

   old  new
0    0    0
1    1    2
2    2    4
3    3    6
4    4    8
5    5   10
6    6   12
7    7   14
8    8   16
9    9   18
Run Code Online (Sandbox Code Playgroud)

  • 我见过的将 pandas 与 asyncio 混合的最巧妙的方法之一。实际上不得不在我的浏览器历史记录中寻找它。哈哈 (4认同)