当前位置:首页 > 文章列表 > 文章 > python教程 > Python多组groupby条形图合并教程

Python多组groupby条形图合并教程

2025-10-26 22:33:36 0浏览 收藏

本文详细介绍了如何利用Python的Pandas和Matplotlib库,巧妙地将基于相同分组但聚合方式不同的数据(如平均值与总和)合并,并以并排条形图的形式进行可视化展示。针对直接使用`groupby().agg().plot.barh()`难以实现多聚合结果并排展示的问题,提出了通过数据框合并和Matplotlib子图功能,配合精细的轴标签设置的解决方案。文章通过实例演示了如何独立聚合数据、合并聚合结果,并利用`barh()`函数调整条形位置和宽度,最终生成清晰直观的对比图,有效提升数据分析报告的可读性和专业性,是数据分析与可视化中一项实用技巧。

在Python中合并并可视化多个groupby聚合条形图

本文详细介绍了如何使用Pandas和Matplotlib将两个基于相同分组但聚合方式不同的数据集(例如,平均值和总和)合并,并在一个条形图中进行并排可视化。通过数据框合并、Matplotlib的子图功能以及精细的轴标签设置,用户可以清晰地对比不同聚合结果,提升数据分析报告的可读性和专业性。

在数据分析工作中,我们经常需要对数据进行分组聚合,并对不同聚合结果进行比较。例如,我们可能需要同时查看某个类别下数据的平均值和总和。虽然Pandas的groupby().agg().plot.barh()可以方便地生成单个聚合的条形图,但要将两个或更多聚合结果并排展示在一个图中,则需要更灵活的方法。本教程将指导您如何通过数据合并和Matplotlib的强大功能实现这一目标。

问题场景

假设我们有一个名为day_df的数据集,其中包含年份(yr)、季节(season)和天气情况(weathersit)等分类变量,以及一个数值变量cnt(计数)。我们希望同时可视化按这三个分类变量分组后的cnt的平均值和总和。

直接尝试将两个groupby().agg().plot.barh()的结果合并到一个图中通常会失败,因为它们生成的是独立的图表。此外,如果尝试手动使用plt.bar()或plt.barh(),可能会遇到索引对齐和标签设置的挑战,尤其是在处理多层索引时。

解决方案核心思路

解决此问题的关键在于:

  1. 独立聚合数据: 分别计算每个分组的平均值和总和。
  2. 合并聚合结果: 将这些独立的聚合结果合并到一个Pandas DataFrame中。
  3. 使用Matplotlib绘制: 利用Matplotlib的barh()(或bar())函数在同一个坐标轴上绘制合并后的数据,并通过调整条形的位置和宽度实现并排显示。

详细步骤与代码示例

1. 准备数据并进行分组聚合

首先,我们需要对原始数据进行两次分组聚合,一次计算cnt的平均值,另一次计算cnt的总和。为了方便后续合并,聚合后需要使用reset_index()将多层索引转换为普通列。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 假设 day_df 是您的原始数据框
# 为了教程的可运行性,这里创建一个模拟数据框
data = {
    'yr': np.random.choice([0, 1], 100),
    'season': np.random.choice([1, 2, 3, 4], 100),
    'weathersit': np.random.choice([1, 2, 3], 100),
    'cnt': np.random.randint(100, 1000, 100)
}
day_df = pd.DataFrame(data)

# 计算每个分组的平均值并重置索引
day_mean_dataframe = day_df.groupby(by=["yr", "season", "weathersit"]).agg({"cnt": "mean"}).reset_index()

# 计算每个分组的总和并重置索引
day_sum_dataframe = day_df.groupby(by=["yr", "season", "weathersit"]).agg({"cnt": "sum"}).reset_index()

print("平均值数据框(部分):")
print(day_mean_dataframe.head())
print("\n总和数据框(部分):")
print(day_sum_dataframe.head())

2. 合并聚合后的数据框

接下来,我们将这两个聚合后的数据框合并。由于它们共享相同的分组键(yr, season, weathersit),我们可以使用pd.merge()函数进行内连接。为了区分聚合结果,我们使用suffixes参数为cnt列添加后缀。

# 合并两个数据框
merged_df = pd.merge(day_mean_dataframe, day_sum_dataframe, 
                     on=["yr", "season", "weathersit"], 
                     suffixes=('_mean', '_sum'))

print("\n合并后的数据框(部分):")
print(merged_df.head())

merged_df现在包含每个分组的cnt_mean和cnt_sum两列,方便我们进行统一绘图。

3. 使用Matplotlib绘制并排条形图

现在,我们可以使用Matplotlib的barh()函数来绘制水平并排条形图。

# 创建图和子图对象
fig, ax = plt.subplots(figsize=(12, 8)) # 调整图大小以适应更多标签

# 为每个分组创建一个位置数组
r1 = np.arange(len(merged_df))
height1 = 0.4 # 设置条形的高度,用于 barh

# 绘制平均值条形
ax.barh(r1, merged_df["cnt_mean"], height=height1, label='平均值 (Mean)', color='skyblue')

# 绘制总和条形,将其位置偏移,实现并排效果
ax.barh(r1 + height1, merged_df["cnt_sum"], height=height1, label='总和 (Sum)', color='lightcoral')

# 设置Y轴刻度标签
# 将刻度放在两个条形之间
ax.set_yticks(r1 + height1 / 2) 
# 生成可读性强的Y轴标签,结合所有分组键
ax.set_yticklabels([f'年份: {row.yr}, 季节: {row.season}, 天气: {row.weathersit}' 
                    for _, row in merged_df.iterrows()])

# 添加图例、轴标签和标题
ax.set_xlabel('计数 (Count)')
ax.set_ylabel('分组类别 (Group Categories)')
ax.set_title('不同分组下计数平均值与总和的对比')
ax.legend()

# 调整布局,防止标签重叠
plt.tight_layout()
plt.show()

代码说明与注意事项

  • reset_index()的重要性: 在groupby().agg()之后调用reset_index()是关键一步。它将多层索引转换为普通列,使得后续的pd.merge()操作更加直接,并且在设置yticklabels时也能方便地访问各个分组键。
  • pd.merge()的suffixes参数: 使用suffixes=('_mean', '_sum')可以避免合并后出现同名列冲突,并清晰地标识出每个聚合结果的来源。
  • np.arange(len(merged_df)): 这创建了一个等差数列,作为每个分组在Y轴上的基准位置。
  • height1和位置偏移: height1定义了每个水平条形的高度。通过将第二个条形的位置设置为r1 + height1,可以使其紧邻第一个条形并排显示。如果使用plt.bar()绘制垂直条形图,则需要调整width和x轴位置。
  • ax.set_yticks()和ax.set_yticklabels(): 对于水平条形图,Y轴代表分组类别。我们需要手动设置Y轴的刻度位置(r1 + height1 / 2将刻度标签置于两个条形之间)和刻度标签。通过遍历merged_df并格式化字符串,可以创建包含所有分组信息的清晰标签。
  • plt.tight_layout(): 这个函数会自动调整子图参数,以给定的填充方式,使之适应图的布局,通常用于防止标签或标题重叠。
  • 可读性: 选择合适的figsize、height(或width)、颜色和字体大小,可以显著提升图表的可读性。对于分组类别较多的情况,水平条形图(barh)通常比垂直条形图(bar)更适合显示长标签。

总结

通过上述步骤,我们成功地将两个基于相同分组但聚合方式不同的数据集(平均值和总和)合并,并在一个清晰的水平条形图中进行了并排可视化。这种方法不仅解决了直接绘制的难题,还提供了高度的灵活性和定制性,使您能够创建专业且易于理解的数据分析图表。掌握这种技术,对于进行多维度数据比较和报告展示非常有价值。

到这里,我们也就讲完了《Python多组groupby条形图合并教程》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于的知识点!

Golang指针数组使用全解析Golang指针数组使用全解析
上一篇
Golang指针数组使用全解析
Golang工厂模式详解与实例教学
下一篇
Golang工厂模式详解与实例教学
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • ChatExcel酷表:告别Excel难题,北大团队AI助手助您轻松处理数据
    ChatExcel酷表
    ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
    3180次使用
  • Any绘本:开源免费AI绘本创作工具深度解析
    Any绘本
    探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
    3391次使用
  • 可赞AI:AI驱动办公可视化智能工具,一键高效生成文档图表脑图
    可赞AI
    可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
    3420次使用
  • 星月写作:AI网文创作神器,助力爆款小说速成
    星月写作
    星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
    4526次使用
  • MagicLight.ai:叙事驱动AI动画视频创作平台 | 高效生成专业级故事动画
    MagicLight
    MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
    3800次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码