如何按年份和地区分组计算均值并为多边形构建生成环状索引(loop ID)

发布时间 - 2026-02-02 00:00:00    点击率:

本文介绍如何在 pandas 中对时间-区域数据分组计算变量均值,并按特定逻辑(lower 升序、upper 降序)排序后分配环状索引(loop),以支持后续多边形(如地理围栏或面积图)的顶点顺序构建。

在可视化或空间分析中,常需将成对的上下边界(如置信区间、预测上下限、地理高程带等)构造成闭合多边形。为此,不仅需要按组聚合统计量(如均值),还需为每组内的观测点分配一个首尾相连的顶点序号(loop ID),确保绘图时能按 0 → 1 → 2 → 3 → 0 的顺序闭合路径。

给定原始数据:

import pandas as pd

mydict = {
    'year': [2010, 2010, 2011, 2011,

2010, 2010, 2011, 2011], 'region': [1, 1, 1, 1, 2, 2, 2, 2], 'group': ['lower', 'upper', 'lower', 'upper', 'lower', 'upper', 'lower', 'upper'], 'var': [10, 20, 30, 40, 50, 60, 70, 80] } df = pd.DataFrame(mydict)

✅ 步骤一:计算每组(year + region)的平均值

使用 groupby(...).transform('mean') 可高效广播均值至每行,无需聚合再合并:

df['average'] = df.groupby(['year', 'region'])['var'].transform('mean')

该列结果为:同一 year-region 组内所有 var 值的算术平均(如 2010-1 组:(10+20)/2 = 15)。

✅ 步骤二:生成环状 loop ID(关键逻辑)

目标是让每个 region 内的四行(2 年 × 2 组)按如下顺序编号:
[2010-lower, 2011-lower, 2011-upper, 2010-upper] → [0, 1, 2, 3]

实现策略:

  • 对 lower 组保留 var 原值(升序排列即按年递增);
  • 对 upper 组取 -var(因 var 本身随年份增大,取负后可使 2011-upper 排在 2010-upper 前,实现“upper 降序”);
  • 按 group(lower 在前)、再按调整后的 var 排序;
  • 对每个 region 内排序后的序列,用 cumcount() 从 0 开始编号。

完整代码如下:

df['loop'] = (
    df.assign(var=df['var'].mask(df['group'].eq('upper'), -df['var']))
      .sort_values(by=['group', 'var'])
      .groupby('region').cumcount()
)
? 关键说明:mask(..., -df['var']) 将 upper 行的 var 替换为负值,使排序时 upper 组内数值越大(如 80→-80),排序越靠前(因 -80

✅ 最终结果验证

执行后,df 包含以下列:

year region group var average loop
2010 1 lower 10 15.0 0
2010 1 upper 20 15.0 3
2011 1 lower 30 35.0 1
2011 1 upper 40 35.0 2
2010 2 lower 50 55.0 0
2010 2 upper 60 55.0 3
2011 2 lower 70 75.0 1
2011 2 upper 80 75.0 2

可见:每个 region 内 loop 均为 [0, 3, 1, 2],对应多边形顶点顺序 (2010-lower, 2010-upper, 2011-lower, 2011-upper) 的逆时针环状连接(实际绘图时按 loop 升序取点即可闭合)。

⚠️ 注意事项

  • 此方法假设每 region 内恰好有 2 个年份 × 2 个 group(共 4 行)。若数据不规则(如缺失某年或某组),需先补全(pd.MultiIndex.from_product + reindex)再应用。
  • loop 是基于 region 分组独立编号的,跨 region 不连续,符合多边形独立绘制需求。
  • 若需适配更多年份(如 3 年),逻辑可扩展为:lower 按年升序,upper 按年降序,再拼接两段索引(np.concatenate([np.arange(n), np.arange(n)[::-1][1:]]))。

该方案兼顾简洁性与可扩展性,是构建动态区间多边形(如 matplotlib.fill_between 或 geopandas.Polygon)的理想预处理步骤。


# go  # 排列  # pandas  # matplotlib  # var  # transform  # 升序  # 均值  # 按年  # 降序  # 每组  # 首尾相连  # 均为  # 将成  # 越大  # 可使 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: javascript中对象的定义、使用以及对象和原型链操作小结  Python文件异常处理策略_健壮性说明【指导】  北京专业网站制作设计师招聘,北京白云观官方网站?  googleplay官方入口在哪里_Google Play官方商店快速入口指南  如何快速辨别茅台真假?关键步骤解析  JS实现鼠标移上去显示图片或微信二维码  Laravel如何使用Collections进行数据处理?(实用方法示例)  制作公司内部网站有哪些,内网如何建网站?  使用豆包 AI 辅助进行简单网页 HTML 结构设计  node.js报错:Cannot find module 'ejs'的解决办法  html5的keygen标签为什么废弃_替代方案说明【解答】  深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?  Laravel请求验证怎么写_Laravel Validator自定义表单验证规则教程  头像制作网站在线观看,除了站酷,还有哪些比较好的设计网站?  夸克浏览器网页跳转延迟怎么办 夸克浏览器跳转优化  如何在IIS中新建站点并解决端口绑定冲突?  如何在IIS管理器中快速创建并配置网站?  Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南  高配服务器限时抢购:企业级配置与回收服务一站式优惠方案  详解jQuery停止动画——stop()方法的使用  Laravel安装步骤详细教程_Laravel环境搭建指南  如何打造高效商业网站?建站目的决定转化率  javascript事件捕获机制【深入分析IE和DOM中的事件模型】  百度输入法ai组件怎么删除 百度输入法ai组件移除工具  Laravel中间件如何使用_Laravel自定义中间件实现权限控制  如何使用 Go 正则表达式精准提取括号内首个纯字母标识符(忽略数字与嵌套)  JavaScript中的标签模板是什么_它如何扩展字符串功能  Android实现代码画虚线边框背景效果  Laravel怎么使用Blade模板引擎_Laravel模板继承与Component组件复用【手册】  Laravel用户认证怎么做_Laravel Breeze脚手架快速实现登录注册功能  韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐  Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?  英语简历制作免费网站推荐,如何将简历翻译成英文?  Laravel Blade组件怎么用_Laravel可复用视图组件的创建与使用  Linux网络带宽限制_tc配置实践解析【教程】  如何快速搭建高效简练网站?  laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法  Laravel 419 page expired怎么解决_Laravel CSRF令牌过期处理  Win11怎么修改DNS服务器 Win11设置DNS加速网络【指南】  JS去除重复并统计数量的实现方法  大同网页,大同瑞慈医院官网?  Laravel怎么处理异常_Laravel自定义异常处理与错误页面教程  打造顶配客厅影院,这份100寸电视推荐名单请查收  如何用AI帮你把自己的生活经历写成一个有趣的故事?  Laravel如何实现本地化和多语言支持_Laravel多语言配置与翻译文件管理  Laravel集合Collection怎么用_Laravel集合常用函数详解  Laravel如何使用Passport实现OAuth2?(完整配置步骤)  php485函数参数是什么意思_php485各参数详细说明【介绍】  清除minerd进程的简单方法  Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】