Pandas使用存储列表的列为键新增额外数据列的高效实现方法
你当前的实现存在明显的性能问题:一方面每次调用自定义函数都会重新执行clean_cities()生成df2,属于重复计算;另一方面iterrows迭代本身效率极低,当数据量较大时耗时会非常夸张。
最优的实现思路是提前把df2拍平生成球队到城市的映射字典,再通过pandas原生的向量化映射方法赋值,完全避免循环操作:
步骤1:一次性生成映射字典(仅需执行一次)
# 提前拉取df2,不用每次查询都重新调用clean_cities df2 = clean_cities() team_city_map = {} for city, team_list in zip(df2["city"], df2["teams"]): for team_name in team_list: team_city_map[team_name] = city
如果存在单个球队对应多个城市的场景,上面的写法会保留df2中最后出现的对应城市,你可以按需调整规则。
步骤2:向量化赋值新列
直接用pandas的map方法完成匹配,是完全的向量化操作,性能远高于自定义apply:
df1["team_city"] = df1["team_name"].map(team_city_map) # 如果需要给匹配不到的球队填充默认值(比如空字符串),可以加fillna # df1["team_city"] = df1["team_name"].map(team_city_map).fillna("")
性能对比说明
这种方案的时间复杂度是O(M + N),其中M是df2所有teams列的元素总个数,N是df1的行数;而你原来的写法时间复杂度是O(N*K)(K是df2的行数),数据量越大,优化后的方案优势越明显,性能提升几十到上百倍都是正常情况。
你这个场景因为涉及到嵌套列表的匹配,pandas没有直接开箱即用的向量化函数,但上面先做结构转换再用map的方案,是这类匹配需求的标准最优实现。
内容的提问来源于stack exchange,提问作者cammyalex
相关产品推荐
相关产品推荐

