ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

08_分组统计

08_分组统计 数据洗干净了接下来干嘛当然是分析。拿到一份月度账单你脑子里大概率会冒出这些问题这个月我吃饭花了多少钱哪一类花得最多平均每笔消费多少钱用微信和支付宝哪个花得多单笔最贵的是哪一笔这些问题的答案一个groupby基本全能搞定。它是 Pandas 里最核心、最常用的技能之一。可以说不会 groupby 就等于不会用 Pandas 做分析。今天我们就拿着一份账单数据一个问题一个问题来回答。先把数据摆出来为了方便演示我们造一份个人账单数据。你跟着敲一遍效果最好。importpandasaspd data{日期:[2026-09-01,2026-09-02,2026-09-02,2026-09-03,2026-09-04,2026-09-05,2026-09-05,2026-09-06,2026-09-07,2026-09-08,2026-09-09,2026-09-10,2026-09-11,2026-09-12,2026-09-13],类别:[餐饮,交通,餐饮,购物,餐饮,交通,娱乐,购物,餐饮,通讯,餐饮,交通,购物,娱乐,餐饮],金额:[35.5,8,42,199,28,6,89,259,56,129,38,15,499,168,45],支付方式:[微信,支付宝,微信,信用卡,微信,支付宝,微信,信用卡,支付宝,信用卡,微信,微信,信用卡,支付宝,微信]}dfpd.DataFrame(data)print(df)一共15笔消费有日期、类别、金额、支付方式四个字段。接下来我们用这份数据回答5个问题。问题1每个类别分别花了多少钱这是最经典的分组求和问题。resultdf.groupby(类别)[金额].sum()print(result)输出类别 娱乐 257.0 交通 29.0 餐饮 244.5 通讯 129.0 购物 957.0 Name: 金额, dtype: float64一目了然——购物花得最多957块。这句代码怎么理解拆成三部分看部分作用df.groupby(类别)按类别列把数据分成好几组[金额]选择要统计的列只看金额这一列.sum()对每组分别求和先分组 → 再选列 → 最后聚合。三步走逻辑很清晰。小细节返回的是什么上面的结果左边是类别名称右边是金额。它不是普通的表格叫Series——一维的带索引。如果你想要一个正经的表格DataFrame加个.reset_index()resultdf.groupby(类别)[金额].sum().reset_index()print(result)类别 金额 0 娱乐 257.0 1 交通 29.0 2 餐饮 244.5 3 通讯 129.0 4 购物 957.0列名清清楚楚看着更舒服。问题2哪一类花得最多排个序看看光知道各花了多少还不够。谁最多、谁最少排一下就知道了。resultdf.groupby(类别)[金额].sum().reset_index()result_sortedresult.sort_values(金额,ascendingFalse)print(result_sorted)输出类别 金额 4 购物 957.0 0 娱乐 257.0 2 餐饮 244.5 3 通讯 129.0 1 交通 29.0ascendingFalse从大到小排降序ascendingTrue从小到大排升序默认值排完序一眼就看到——购物是大头占了总支出的近六成。来个 Top 3排序 head 组合就是经典的 Top Ntop3result.sort_values(金额,ascendingFalse).head(3)print(top3)购物、娱乐、餐饮是花钱最多的前三名。问题3每类平均每笔花多少钱笔数呢光看总额不够全面。比如餐饮总额244.5但可能吃了10顿交通总额29但可能只有3笔。单价完全不一样。这就需要同时算好几个指标。用agg()resultdf.groupby(类别)[金额].agg(总金额sum,笔数count,平均金额mean).reset_index()print(result.sort_values(总金额,ascendingFalse))输出类别 总金额 笔数 平均金额 4 购物 957.0 3 319.000000 0 娱乐 257.0 2 128.500000 2 餐饮 244.5 6 40.750000 3 通讯 129.0 1 129.000000 1 交通 29.0 3 9.666667一行代码总额、笔数、平均值全出来了。可以看到餐饮虽然总金额排第三但笔数最多6笔平均每顿才40块。购物就3笔但平均单笔300多——对比很直观。agg()是我写代码时最常用的 groupby 搭配。不用分别跑好几遍一次算完列名还能自己起成中文可读性高。常用聚合函数sum求和、mean平均、count计数、max最大、min最小、std标准差。知道这几个绝大多数场景都够用了。问题4不同支付方式分别花了多少这个问题跟问题1是一样的思路只是分组的列从类别换成了支付方式pay_spenddf.groupby(支付方式)[金额].agg(总金额sum,笔数count).reset_index()print(pay_spend.sort_values(总金额,ascendingFalse))支付方式 总金额 笔数 0 信用卡 1086.0 4 1 微信 292.5 7 2 支付宝 238.0 4信用卡占了大头主要是购物那几笔大额都走了信用卡。如果想同时按类别支付方式分组呢有时候你想知道——餐饮里微信花了多少、支付宝花了多少这就需要按两个列分组resultdf.groupby([类别,支付方式])[金额].sum().reset_index()print(result.head(10))groupby传一个列表进去就行几列都可以。结果会是一个长表格每一行是类别 支付方式的组合。如果组合太多看起来乱可以配合排序或者透视表来看——透视表我们后面导出报表那篇会讲。问题5单笔最高消费是哪一笔这个问题有点不一样。不是求某个统计值而是想找到具体那一行数据。你可能想这么写# 思路不对——这样只能拿到最大金额不知道是哪一笔print(df.groupby(类别)[金额].max())这只能看到每类的最大值但看不到完整的消费信息。正确姿势用idxmax()找到最大值所在的行索引再用loc取整行。max_indexdf[金额].idxmax()max_rowdf.loc[max_index]print(单笔最高消费)print(max_row)输出单笔最高消费 日期 2026-09-11 类别 购物 金额 499.0 支付方式 信用卡 Name: 12, dtype: objectidxmax()返回最大值所在行的索引再用.loc取整行——完整信息全出来了。延伸一下想知道每个类别里最贵的那一笔先分组再用applynlargest。这个稍微进阶一点先知道有这么个东西等你需要的时候能想起来就行。真实运行效果下面把这份账单代码在本地真实跑一遍5 个问题的输出原样贴出来。截图从每类消费合计、按金额降序排序、agg 一次算出总额/笔数/均值到按支付方式分组、再用 idxmax 定位出单笔最高那笔9-11 购物 499 元全部是代码直接打印的真实结果。5个问题答完了捋一捋用一份账单数据回答了5个问题用到的全是 groupby 相关的技能。汇总一下问题用什么每类花了多少groupby sum谁花得最多sort_values排序 head取Top N每类平均/笔数/总额agg()一次算多个按不同维度分组groupby换列就行多列传列表单笔最高是哪笔idxmax()找索引 loc取行说到底就三步先分组再选列最后聚合。顺序别乱逻辑就清晰。新手常见的3个坑最后说几个 groupby 新手最容易踩的坑提前避开。坑1groupby 之后直接 sum()出来一堆列df.groupby(类别).sum()这样写会把所有数值列都求和。我们这份数据只有金额是数值列所以问题不大如果有好几个数值列它会全部求和结果很乱。好习惯先选列再聚合写完整df.groupby(类别)[金额].sum()坑2聚合后列名看不懂用sum()返回的列名还是金额用agg([sum, count])列名就是英文的 sum、count。时间长了自己都忘了啥意思。好习惯用 agg 的关键字参数方式自己起列名df.groupby(类别)[金额].agg(总金额sum,笔数count)代码可读性直接上一个台阶。坑3忘了 reset_index结果索引怪怪的groupby 默认会把分组键类别名变成索引。如果你想要一个普通表格记得加.reset_index()。不然后面用列名筛选数据的时候你会发现类别这列怎么都找不到——它在索引里呢。写在最后分组统计这事说白了就是把账单按类别切开每堆各自算一笔。但这玩意儿真不需要背——拿自己的真实账单练几次就什么都会了。毕竟花的是自己的钱分析起来比练习题有动力多了 下一篇我们讲数据筛选——布尔索引、loc、条件组合教你怎么从几万条数据里精准捞出来你想要的那几条。梅雅达编程工作室 · Python数据实战系列第8篇先分组、再选列、最后聚合——顺序记住了groupby 就是数据分析里最顺手的那把刀。
返回列表