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

优化DatetimeIndex嵌套循环:高效转换多国家时序DataFrame

高效实现DataFrame格式转换(替代嵌套循环)

你的需求是把含小时级数据的宽表转换成MultiIndex列(国家代码+年份)、索引为一年中小时位置(0-8759)的格式,用来绘制年度箱线图。原来的嵌套循环因为逐列逐行赋值,效率很低,我们可以利用pandas的矢量化操作和内置函数大幅提升速度。

优化方案代码

# 直接用groupby+apply+concat实现批量转换
ds = pd.concat(
    [
        col.groupby(df.index.year).apply(lambda x: x.reset_index(drop=True))
        for _, col in df.items()
    ],
    axis=1,
    keys=df.columns
)

# 如果需要强制统一为8760行(处理闰年多出来的24小时),可以修改apply部分:
# ds = pd.concat(
#     [
#         col.groupby(df.index.year).apply(lambda x: x.reset_index(drop=True).iloc[:8760])
#         for _, col in df.items()
#     ],
#     axis=1,
#     keys=df.columns
# )

方案解释

  1. 分组处理单个国家的数据:对每个国家的列(col),按年份分组(groupby(df.index.year)),然后用apply(lambda x: x.reset_index(drop=True))把每组的小时数据重置索引为0-8759(或闰年的0-8783),这样每个年份对应一个长度一致的Series。
  2. 批量拼接结果:用pd.concat把所有国家的处理结果按列拼接,keys=df.columns参数会自动把国家代码作为MultiIndex的上层,年份作为下层,正好得到你需要的列结构。

为什么比原代码快?

原代码的嵌套循环中,每次ds.loc[:, (reg, year)] = ...都会修改整个DataFrame,触发多次内存复制,当数据量较大(28个国家×30年)时,效率会急剧下降。而优化方案利用pandas的批量处理逻辑,所有操作都是在底层矢量化执行,避免了逐元素赋值的开销,速度能提升数倍甚至数十倍。

验证效果

转换完成后,你可以直接用ds[('CN', 2020)].plot(kind='box')这样的代码绘制单个国家某一年的箱线图,和原代码的输出效果完全一致,但执行效率大幅提升。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:46:17