for循环迭代累加数据构建pandas DataFrame的实现方案咨询
解答
你所说的「先创建空DataFrame再逐次追加」的方案完全可以实现需求,不过你的现有代码存在一些重复冗余的逻辑,调整后运行效率会更高,也能避免潜在报错。
现有代码可优化点
- 不要在for循环内部重复调用
nest_asyncio.apply(),全局执行一次即可 - 不要在for循环内部重复定义异步函数,将异步逻辑抽取出循环外,避免重复创建函数对象
- 不要在for循环内部重复创建事件循环,统一在循环外处理事件逻辑即可
- 目前pandas较高版本已经弃用了
DataFrame.append()方法,更推荐使用pd.concat()实现数据追加,兼容性和性能更好
调整后可直接运行的代码
import pandas as pd import asyncio import aiohttp from understat import Understat import nest_asyncio # 全局执行一次即可 nest_asyncio.apply() async def fetch_single_player_data(player_id, session): understat = Understat(session) shots_data = await understat.get_player_shots( player_id, {"season": "2020", "situation": "OpenPlay"} ) return pd.DataFrame(shots_data) async def collect_all_data(player_ids_list): # 初始化空DataFrame用于存储全量数据 all_data = pd.DataFrame() async with aiohttp.ClientSession() as session: for pid in player_ids_list: # 单次获取单个球员的数据 single_df = await fetch_single_player_data(pid, session) # 追加到总表 all_data = pd.concat([all_data, single_df], ignore_index=True) return all_data if __name__ == "__main__": # 替换为你的实际球员id列表 player_ids = [xxx, xxx, xxx] loop = asyncio.get_event_loop() final_result_df = loop.run_until_complete(collect_all_data(player_ids))
补充说明
如果你使用的pandas版本较低,append方法还未被移除,也可以将追加数据的代码替换为all_data = all_data.append(single_df, ignore_index=True),功能完全一致。
如果需要进一步提升请求效率,可以将所有球员的请求协程先存入列表,用asyncio.gather批量并发执行后再一次性合并数据,不用等待上一个请求完成再发下一个请求。
内容的提问来源于stack exchange,提问作者SymereWoods
相关产品推荐
相关产品推荐

