You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jupyter中异步填充Pandas DataFrame遇RuntimeError问题求助

问题原因与解决方案

1. RuntimeError的直接原因

Jupyter Notebook(包括同类交互式Python环境)默认已经启动了一个asyncio事件循环,而asyncio.run()的设计目标是在无事件循环的环境中启动新循环。当你在已有运行中的循环里调用它时,就会触发这个错误——asyncio不允许嵌套运行事件循环。

2. 代码中的其他核心问题

除了事件循环冲突,你的代码还有一个关键问题:pandas.Series.apply()是同步方法,直接传入async函数fetch_status的话,不会等待协程执行完成,反而会返回一堆未执行的coroutine对象,根本拿不到实际的状态码。

修正后的完整代码

方式1:适配Jupyter环境的最简写法

import asyncio
import pandas as pd
import requests

mydf = pd.DataFrame({'url':['https://google.com','https://apple.com']})
print(mydf)
print("-----")

async def fetch_status(url: str) -> int:
    # 用to_thread把同步的requests.get放到线程池执行,不阻塞事件循环
    response = await asyncio.to_thread(requests.get, url)
    return response.status_code

async def main_task() -> None:
    # 批量创建协程任务,替代无法处理async的apply方法
    tasks = [fetch_status(url) for url in mydf['url']]
    # 等待所有任务完成,获取结果列表
    status_codes = await asyncio.gather(*tasks)
    # 把结果赋值给新列
    mydf['status'] = status_codes
    print(mydf)

# Jupyter中直接用await运行协程,不需要asyncio.run()
await main_task()

方式2:兼容Jupyter和普通脚本的通用写法

如果想让代码同时在Jupyter和普通Python脚本中运行,可以添加环境判断:

# 放在main_task函数定义之后
try:
    # 尝试获取当前已运行的事件循环
    loop = asyncio.get_running_loop()
    if loop.is_running():
        # Jupyter环境下直接await
        await main_task()
except RuntimeError:
    # 无运行中的循环,用asyncio.run()启动
    asyncio.run(main_task())

关键说明

  • 放弃用pandas.apply()处理async函数,改用asyncio.gather()批量执行协程,这是asyncio处理批量异步任务的标准方式。
  • Jupyter中直接用await关键字运行协程即可,无需调用asyncio.run()。
  • asyncio.to_thread()用来把同步的requests.get包装成可await的对象,避免阻塞事件循环;如果追求更原生的异步HTTP请求,可以改用aiohttp库。

内容的提问来源于stack exchange,提问作者Odyseus_v4

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 17:56:06