如何计算Pandas DataFrame子序列均值并优化人均GDP分年代分析代码
解决方案
一、年代平均增长率计算优化
你原来的两层循环可以完全替换为pandas向量化操作,代码如下:
import pandas as pd import wbgapi as wb # 拉取原始数据 gdp = wb.data.DataFrame('NY.GDP.PCAP.KD.ZG').reset_index() # 宽表转长表,方便后续分组计算 gdp_long = gdp.melt(id_vars='economy', var_name='year', value_name='gdp_growth') # 提取年份数值,计算所属年代 gdp_long['year'] = gdp_long['year'].str.replace('YR', '').astype(int) gdp_long['decade'] = (gdp_long['year'] // 10) * 10 # 过滤1960年及以后数据,按国家、年代分组计算均值 meandata = gdp_long[gdp_long['decade'] >= 1960].groupby(['economy', 'decade'], as_index=False)['gdp_growth'].mean() # 重命名列匹配你的需求,同时初始化Region列 meandata.columns = ['Country', 'Decade', 'MeanGDP'] meandata['Region'] = ''
相关疑问解答
- 这个方案完全基于pandas内置的向量化操作,不需要手动遍历行/列,性能比嵌套循环提升至少10倍以上,数据量越大优势越明显。
- 你原来的两层循环不是严格的O(n²):外层循环次数是国家数量N,内层循环次数是固定的年代数(1960年至今只有7个年代,属于常数C),理论上时间复杂度应为O(N)。但你每次循环都调用
append方法修改DataFrame,而append会生成全新的DataFrame,时间复杂度随当前DataFrame长度线性增长,最终实际运行效率接近O(n²)。
二、区域匹配优化
报错说明
'meandata' is not defined报错和代码本身无关,是JupyterLab的单元格执行顺序问题:如果生成meandata的单元格没有执行成功,或者你先执行了区域匹配的单元格,就会触发该报错,只要按顺序从上到下执行所有单元格即可解决。
高效实现方案
不用循环逐行匹配,先提前生成国家到区域的映射字典,再批量赋值即可,代码如下:
# 生成国家-多区域的映射字典 country_region_map = {} for rg in wb.region.list(): rg_code = rg['code'] for co in wb.region.members(rg_code): country_region_map.setdefault(co, []).append(rg_code) # 将区域列表拼接为-分隔的字符串 for k, v in country_region_map.items(): country_region_map[k] = '-'.join(v) # 批量映射到meandata的Region列 meandata['Region'] = meandata['Country'].map(country_region_map)
该方案只需遍历一次所有区域和对应国家,再做一次批量赋值,时间复杂度仅为O(R*M + N)(R为区域总数、M为单区域国家数、N为meandata行数),比原有实现效率高很多。
三、通用优化建议
- 尽量避免手动写for循环遍历DataFrame的行/列,优先使用pandas内置的
melt、groupby、map等向量化操作,性能差距可达几十到上百倍。 - 不要频繁调用
append修改DataFrame,该操作会反复拷贝全量数据,效率极低。如果必须收集循环结果,建议先存在普通列表中,最后一次性转换为DataFrame。 - 涉及到值匹配/替换的场景,优先用字典+
map的批量操作,不要逐行筛选赋值。 - Jupyter环境中要注意单元格执行顺序,依赖的变量必须提前执行对应生成代码,避免变量未定义报错。
内容的提问来源于stack exchange,提问作者R. L.
相关产品推荐
相关产品推荐

