双重循环致DataFrame无限加载,求高效行比较优化方案
问题解决:用Pandas内置方法替代低效双重循环
你的代码卡顿的核心原因是双重循环带来的O(n²)时间复杂度——3万行数据会产生近9亿次迭代,完全不符合Pandas的高效处理范式。以下是针对性的优化方案:
1. 重构「美食风格字段展开」逻辑
原代码通过循环解析列表并拼接新行,可直接用Pandas的explode方法替代,效率提升显著:
import pandas as pd import ast # 移除不需要的列 df6 = reviews.drop(reviews.columns[[4, 5, 6]], axis=1) # 将字符串格式的列表转为Python列表 df6['Estilo Culinário'] = df6['Estilo Culinário'].apply(ast.literal_eval) # 展开列表列,生成对应新行 df6b = df6.explode('Estilo Culinário').rename(columns={'Estilo Culinário': 'Estilo'}) # 保留目标列并清理空值,同时转换排名为数值类型 df6b = df6b[['Nome', 'Cidade', 'Estilo', 'Ranking']].dropna() df6b['Ranking'] = df6b['Ranking'].astype(float)
2. 用分组操作替代双重循环筛选
原代码的逻辑是:在同一Cidade+Estilo组内,删除所有排名大于等于组内其他行的记录,最终保留组内排名最小的行。用groupby+idxmin可以一步实现:
# 按城市+美食风格分组,获取每组中排名最小的行的索引 min_rank_indices = df6b.groupby(['Cidade', 'Estilo'])['Ranking'].idxmin() # 筛选出目标行 df6b_filtered = df6b.loc[min_rank_indices].reset_index(drop=True)
若需求为保留排名最高的行(修正原逻辑可能的反向)
如果你的实际需求是保留同一城市+风格下排名最优(比如数字越小排名越高)的行,只需将idxmin替换为idxmax:
max_rank_indices = df6b.groupby(['Cidade', 'Estilo'])['Ranking'].idxmax() df6b_filtered = df6b.loc[max_rank_indices].reset_index(drop=True)
3. 最终输出处理
df6c = df6b_filtered.drop('Estilo', axis=1) df6c
效率提升的核心原因
- Pandas的
explode、groupby等方法基于底层C语言实现,比Python循环快100~1000倍 - 避免了循环中频繁修改DataFrame(
inplace=True会触发多次数据重排,严重拖慢速度)
内容的提问来源于stack exchange,提问作者João Pedro Leite
相关产品推荐
相关产品推荐

