Pandas.DataFrame.groupby() 数据分组(数据透视、分类汇总) 详解 含代码 含测试数据集 随Pandas版本持续更新

关于Pandas版本: 本文基于 pandas2.1.2 编写。

关于本文内容更新: 随着pandas的stable版本更迭,本文持续更新,不断完善补充。

Pandas稳定版更新及变动内容整合专题: Pandas稳定版更新及变动迭持续更新。

Pandas API参考所有内容目录

本节目录

  • Pandas.DataFrame.groupby()
    • 语法:
    • 返回值:
    • 参数说明:
      • by 指定分组依据
      • axis 指定分割方向
      • level 指定多层索引的层级编号或层级名称
      • as_index 排序方法(升序或降序)
      • sort 是否对组名排序
      • group_keys 是否返回组键
      • observed 只显示观测值或显示所有值
      • dropna 其他排序置
    • 相关方法:
    • 示例:

Pandas.DataFrame.groupby()

DataFrame.groupby() 方法用于使用映射器或指定的列,对 DataFrame 进行数据分组,可以实现类似Excel的数据透视、分类汇总的效果。

  • DataFrame.groupby() 的底层逻辑是:

    • 1、根据指定的规则(由 by 参数指定)分割 DataFramegroupby 对象;
      • 此时只是完成了 DataFrame 分割,仅仅是一个 groupby 对象,还没有完成汇总。这意味着无法像观察 DataFrame 一样观察它:
      • 可以使用 for 循环观察groupby 对象。 例1
      • 用于分组的分类内容,默认会作为这个新 DataFrame 的索引(行索引,或列名,具体视汇总方向而定)。例2-5
    • 2、应用指定的方法,汇总、聚合被分割的数据。
      • 如果应用一种汇总计算方法,所有列都是用一种汇总方法进行聚合。例2
      • 也可以通过 DataFrame.agg 指定不同的列使用不同的计算方法作为汇总方式。例2-4
    • 3、应用聚合方法之后,DataFrame.groupby() 会自动的将聚合后的数据合并为新的 DataFrame

    ⚠️ 注意:

    1、数据分割实际上是基于行索引进行的。

    2、你指定的分割依据(分组依据)需要尽可能的,和行索引等长。

数据分组流程示意图

数据分组流程示意图

语法:

DataFrame.groupby (by=None, axis=_NoDefault.no_default, level=None, as_index=True, sort=True, group_keys=True, observed=_NoDefault.no_default, dropna=True)

返回值:

  • pandas.api.typing.DataFrameGroupBy
    • 返回包含分组信息的 groupby 对象。

参数说明:

by 指定分组依据

  • **by:**mapping, function, label, pd.Grouper or list of such

    by 参数用于指定分组的依据(即分割DataFrame的依据):

  • label(列名):用于把某列指定为分组依据
    • 当某列的数据具有分类特性,指定这个列的列名,作为分组依据 DataFrame例1

  • mapping(映射):用于直接把行索引的值指定为分组依据
    • dict(字典):适用于行索引的值可以拿来做分组(常用于分组名称的重命名) 例3
      • 传递一个字典,字典的键是行索引里的可以作为分组的值,字典的值你自定义的分组名;
      • 注意!如果只传递字典,你需要提前准备好行索引。并且行索引里的值,应该是可以有效分组的。
    • Series(序列):适用于你有一个和 DataFrame 行索引等长的 Series 例4
      • 这个 Series 里的值,应该是可以有效分组的;
      • 这个 Series 建议和 DataFrame 行索引等长;
      • 如果这个Series 必须和 DataFrame 行索引不等长,会自动进行对齐(.align()),二者数据量如果差距太大,会产生很多缺失值,造成分组后计算不精准的结果。

  • function(函数): 函数将作用于行索引的每个值,并使用处理后的值,作为分组依据。 例5
    • 行索引中被函数处理后的值,并不会影响计算前的 groupby 对象。例5-1
    • 行索引中被函数处理后的值,将展示在完成分组计算,合并后的 DataFrame例5-2

  • pd.Grouper:通常用于按照时间间隔分组,直接作用于行索引 例6

  • list of such:多个列构成多维度分组汇总
    • 列名列表: 常用于多维度分组汇总,列表里的第1个列名,默认作为顶层行索引,和其他列名构成多层索引。 例7

axis 指定分割方向

  • axis: {0 or ‘index’, 1 or ‘columns’}, default 0

    axis 参数用于指定分割方向(可以参照此图,了解什么是分割 数据分组流程示意图):

    • 0 or ‘index’: 默认为按行索引分割。
    • 1 or ‘columns’: 按列分割。

    弃用于 Pandas 2.1.0 :

    • axis=1Pandas 2.1.0 版本标记为弃用。使用以下替代方法实现:

      • 先 转置 再 分组 frame.T.groupby(...) 例8
    • 这样做的目的是:使分组后数据尽可能的保持更多的操作性和可读性。

level 指定多层索引的层级编号或层级名称

  • level: int, level name, or sequence of such, default None 例9

    如果 DataFrame 具有多层索引,可以用level参数指定级别的编号或名称,不能和 by 参数同时使用。

    • int:整数层级编号 可以用 整数层级编号 指定分组依据。例9-2
    • level name:层级名称 可以用层级名称, 指定分组依据。例9-2
    • sequence of such:层级编号列表,或层级名称列表 可以用层级编号列表,或层级名称列表指定多个分组依据,类似于 by 参数传递列名列表。例9-3

as_index 排序方法(升序或降序)

  • as_index: bool, default True 例10

    as_index 参数控制是否将组标签作为索引返回。

    • as_index=True 时,组标签将成为输出 DataFrame 的索引。
    • as_index=False 时,组标签不会成为索引,而是返回一个类似 SQL 风格的输出。

sort 是否对组名排序

  • sort: bool, default True 例11

    sort 参数用于控制是否对分组名进行排序,默认 sort=True 会对组名进行排序。此参数不会影响每个组内观察值的顺序:

    • True:分组名进行排序。
    • False: 关闭分组名排序,如果关闭,则组将按其在原始 DataFrame 中的顺序显示,可以获得更高的性能。

    📌 改动于 Pandas 2.0.0 :

    自 Pandas2.0.0 开始,当使用 有序分类 数据进行分组,当 sort=False 将不再对其进行排序。

    在之前的版本中(2.0.0 之前),即使设置了 sort=False,对于有序分类,仍然会对分类进行排序。而在 2.0.0 版本中,这个行为发生了变化,即设置 sort=False 不再影响有序分类的排序,保留原始顺序。

    这个改动的目的是为了提供更一致的行为,使得在使用 sort=False 时,无论分类是否有序,都不再对分类进行排序,从而减少用户的困惑。

group_keys 是否返回组键

  • group_keys: bool, default True

    分组的键指的是 groupby 对象 各分组的行索引

    当使用 groupby 调用 applyby 参数生成分组结果时, 并且 结果行索引数量groupby 对象分组数量 不匹配(不匹配则意味着无法汇总),则默认会将 groupby 对象各分组的行索引结果行索引 组合为多层行索引,以便观察。 例12

    • group_keys=True 时(默认值),分组的键会作为结果的索引。这意味着返回的对象会是一个带有分组键的多层次索引的 DataFrame(或者 Series,具体取决于你应用 groupby 的对象是 DataFrame 还是 Series)。
    • group_keys=False 时,分组的键不会作为索引,而是返回一个不带有分组键的普通 DataFrame(或者 Series)。 例12-3

    📌 **改动于 Pandas 1.5.0 :

    当使用 groupby 调用 applyby 参数生成分组结果时,并且结果行索引数量 和 groupby 对象分组数量 不匹配(不匹配则意味着无法汇总),则需要显式指定 group_keys 是否包含组键。

    📌 **改动于 Pandas 2.0.0 :

    group_keys 默认为 True

observed 只显示观测值或显示所有值

  • observed: bool, default False

    观察值是指在实际数据中存在的唯一分类值。当应用 groupby 操作时,有时可能会遇到分类分组器中存在的分类值,但在实际数据中并未出现的情况。observed 参数允许你控制在分组操作中如何处理这些未观察到的分类值:

    • True: 只显示分类分组器(groupers)的观察值(observed values),而不显示未观察到的值。
    • False: 则显示所有分类分组器的可能值,包括未在实际数据中观察到的值。

    弃用于 Pandas 2.1.0 :

    自2.1.0版本以来已弃用:在panda的未来版本中,默认值将更改为True。

dropna 其他排序置

  • dropna: bool, default True 例13

    dropna 用于控制 groupby 对象的行数索引是否可以包含缺失值:

    • 如果为 True,并且组键包含缺失值,则将 缺失值与行/列一起删除。
    • 如果为 False,则保留缺失值。

    ⚠️ 注意 :

    舍弃缺失值的动作,是在分组前完成的,也就是说,在生成 groupby 分组对象的时候,就已经没有缺失值了。例13-2

相关方法:

➡️ 相关方法


  • resample

    Convenience method for frequency conversion and resampling of time series.

示例:

测试文件下载:

本文所涉及的测试文件,如有需要,可在文章顶部的绑定资源处下载。

若发现文件无法下载,应该是资源包有内容更新,正在审核,请稍后再试。或站内私信作者索要。

测试文件下载位置.png


例1:如果没有指定聚合计算方法,分组结果将是一个 groupby 对象,只能通过 for 循环观察数据内容

  • 例1-1、准备演示数据
import pandas as pd# 读取一个演示文件
df = pd.read_excel("../../../../数据集/团队成员季度销售额.xlsx")
# 观察数据内容
df.sample(5)
姓名片区1季度2季度3季度4季度year
18邹小琴华南40386053469111782023
4左美华华南5792944340873652023
84祝成云华东11863155197519222023
47紫薇华北17284802185769882023
40邹博文华北34345814133490612023
  • 例1-2、用 片区列 分组,但是不传递聚合计算方法
grouped = df.sample(5).groupby(by="片区")
grouped
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x000001F9031CB800>

由上面结果可以发现,无法直接观察 GroupBy 对象

  • 例1-3、使用 for 循环观察分组内容
for group_name, group_data in grouped:print(f"Group: {group_name}")print(group_data)print("\n")
Group: 华中姓名  片区   1季度   2季度   3季度   4季度  year
73  庄海彬  华中  2534   968  4128  5454  2023
59  卓小珍  华中  3274  5837  3025  7993  2023Group: 华北姓名  片区   1季度   2季度   3季度   4季度  year
95  张华丽  华北  4584  1072  3029  8976  2023
48   紫湉  华北  3046  3918  6908  6444  2023Group: 华南姓名  片区  1季度   2季度   3季度   4季度  year
97  王娟  华南  661  6784  3660  8621  2023


例2:分组后,指定汇总计算方式,即可自动完成最终的合并过程,并生成新的 DataFrame

  • 例2-1、构建演示数据并观察数据内容
import pandas as pd# 读取一个演示文件
df = pd.read_excel("../../../../数据集/团队成员季度销售额.xlsx")
# 观察数据内容
df.sample(5)
姓名片区1季度2季度3季度4季度year
71庄骏华中47132588648062242023
27邹立文华北15474927469385262023
38邹凤艳华北20555330646872292023
0左院梅华南14911083500094612023
77祝艳斌华东51611639129175282023

  • 例2-2、以片区列 作为分组依据,只传递一种求和的计算方法。
grouped = df.groupby(by="片区").sum()
grouped
姓名1季度2季度3季度4季度year
片区
华东转身,泪倾城筑梦祝艳斌祝艳祝小娟祝仙花祝卫平祝玛拉初祝海英祝成云竹林听雨竹合竹猪哥传说诸子燕...5372062152771858527136414
华中梓英籽艺子鱼子墨子岚子和子菡资格卓越卓小珍卓向吴追影追忆追梦状之元巍笑吧庄臻庄永奇庄晓运庄...8624911993411950115388954621
华北邹美金邹灵美邹林华邹立文邹黎邹娟利邹杰邹建军邹建华邹吉宏邹积杰邹海利邹贵滨邹广坤邹凤艳邹昌乐...7277612546712000218655058667
华南左院梅左艳艳左薇左娜左美华左梅香左火英左儿左成娟醉霖~棉花糖最终幻想走向幸福邹邹邹子龙邹忠珠...608221096548934214389652598

以片区为分组依据,并传递了求和方法后,姓名列因为是字符串,所以相当于拼接。1季度、2季度、3季度、4季度、year等列,完成了求和计算。

  • 例2-3、指定计算方法,作为汇总方式,即可观察数据分组后的数据了。
grouped = df.groupby(by="片区").sum()
grouped
姓名1季度2季度3季度4季度year
片区
华东转身,泪倾城筑梦祝艳斌祝艳祝小娟祝仙花祝卫平祝玛拉初祝海英祝成云竹林听雨竹合竹猪哥传说诸子燕...5372062152771858527136414
华中梓英籽艺子鱼子墨子岚子和子菡资格卓越卓小珍卓向吴追影追忆追梦状之元巍笑吧庄臻庄永奇庄晓运庄...8624911993411950115388954621
华北邹美金邹灵美邹林华邹立文邹黎邹娟利邹杰邹建军邹建华邹吉宏邹积杰邹海利邹贵滨邹广坤邹凤艳邹昌乐...7277612546712000218655058667
华南左院梅左艳艳左薇左娜左美华左梅香左火英左儿左成娟醉霖~棉花糖最终幻想走向幸福邹邹邹子龙邹忠珠...608221096548934214389652598

  • 例2-4、不同的列指定不同的汇总方式,没有指定汇总方式的列,不会出现在汇总结果。例如 姓名列。
grouped = df.groupby(by="片区").agg({"1季度": "max", "2季度": "mean", "3季度": "sum", "4季度": "min"}  # 最大值  # 平均值  # 总和
)  # 最小值
grouped
1季度2季度3季度4季度
片区
华东51613452.888889771851066
华中53084442.0000001195011684
华北45844326.4482761200021136
华南50704217.461538893421055

  • 例2-5、用于分组的分类数据,在完成数据分组后,会作为索引使用(行索引或列名,具体视分组方向而定)
grouped.axes
[Index(['华东', '华中', '华北', '华南'], dtype='object', name='片区'),Index(['1季度', '2季度', '3季度', '4季度'], dtype='object')]


例3:使用字典数据分组(直接把行索引里的值用字典的方式,指定为分组依据)

  • 例3-1、构建演示数据并观察数据内容
import pandas as pd# 读取一个演示文件
df = pd.read_excel("../../../../数据集/团队成员季度销售额.xlsx")
# 将 片区列,设置为索引
df.set_index("片区", inplace=True)
# 观察数据内容
df.sample(5)
姓名1季度2季度3季度4季度year
片区
华东李先锋40574953677617232023
华南邹小琴40386053469111782023
华中子墨33931562360772732023
华北邹娟利38402815655132172023
华南邹秀珍32051772153469952023
  • 例3-2、 by 参数传入字典,字典的键是 DataFrame 行索引里的值,字典的值是分组名;
grouped = df.groupby(by={"华东": "东部战区", "华南": "南部战区", "华北": "北部战区", "华中": "中部战区"}).agg({"1季度": "max", "2季度": "mean", "3季度": "sum", "4季度": "min"}  # 最大值  # 平均值  # 总和
)  # 最小值
grouped
1季度2季度3季度4季度
片区
东部战区51613452.888889771851066
中部战区53084442.0000001195011684
北部战区45844326.4482761200021136
南部战区50704217.461538893421055


例4:使用Series数据分组(用Series替换当前行索引,并使用里面的值作为分组依据)

  • 例4-1、构建演示数据并观察数据内容
import pandas as pd# 读取一个演示文件
df = pd.read_excel("../../../../数据集/团队成员季度销售额.xlsx")
# 观察数据内容
df.sample(5)
姓名片区1季度2季度3季度4季度year
60卓向吴华中47131691239892702023
43自在华北23544605592886142023
63追梦华中26896790424776372023
17邹秀珍华南32051772153469952023
42自在小英华北21002230340935722023
  • 例4-2、使用Series,构建数据分组。(为了方便,我们把片区列拿过来作为Series做演示)
# 提取片区列作为Series
s = df["片区"].copy(deep=True)# 使用Series,构建数据分组
grouped = df.groupby(by=s).max()
grouped
姓名片区1季度2季度3季度4季度year
片区
华东转身,泪倾城华东51616753677692842023
华中邹世军华中53087377720492702023
华北邹黎华北45847421694592302023
华南醉霖~棉花糖华南50707412597194612023


例5:使用函数数据分组(函数将作用于行索引的每个值)

  • 例5-1、构建演示数据并观察数据内容
import pandas as pd# 读取一个演示文件
df = pd.read_excel("../../../../数据集/团队成员季度销售额.xlsx")
# 将 片区列,设置为索引
# df.set_index('片区',inplace=True)
# 观察数据内容
df.sample(5)
姓名片区1季度2季度3季度4季度year
38邹凤艳华北20555330646872292023
35邹海利华北38755799405783442023
83祝海英华东10181430484571552023
92邹世军华中43434866274376172023
11走向幸福华南43122189443174932023

  • 例5-1、当前行索引是自然索引,我想按照行索引的单数、双数进行分组,可以这样做:
# 定义区分单数双数的函数
def rename_index(index):if index % 2 == 0:return "双数"else:return "单数"# 应用这个函数,处理行索引进行分组
grouped = df.sample(12).groupby(by=rename_index)# 查看group对象里的内容
for group_name, group_data in grouped:print(f"Group: {group_name}")print(group_data)print("\n")
Group: 单数姓名  片区   1季度   2季度   3季度   4季度  year
37   邹广坤  华北  3015  5912  2120  3750  2023
77   祝艳斌  华东  5161  1639  1291  7528  2023
97    王娟  华南   661  6784  3660  8621  2023
89   诸子燕  华东  2454  1824  3306  4198  2023
79   祝小娟  华东  4419  6753  2838  1066  2023
11  走向幸福  华南  4312  2189  4431  7493  2023
63    追梦  华中  2689  6790  4247  7637  2023Group: 双数姓名  片区   1季度   2季度   3季度   4季度  year
34  邹积杰  华北  2175  4902  4874  3110  2023
92  邹世军  华中  4343  4866  2743  7617  2023
8   左成娟  华南  1747  5823  1480  7025  2023
76   筑梦  华东  1856  3905  5808  6265  2023
98   刘贤  华东  3960  6437  3148  1517  2023

从上面这个结果可以发现,函数处理并没有影响到 groupby 对象

  • 例5-2、函数处理行索引的结果,会展现在汇总计算后,合并的新 DataFrame
# 给分组对象一个计算方式,完成最终数据合并,并观察
grouped.max()
姓名片区1季度2季度3季度4季度year
单数邹广坤华南51616790443186212023
双数邹积杰华南43436437580876172023

从上面可以发现,如果 by 参数传递了函数,被修改的 行索引 只会作为分组依据、和分组名称,出现在汇总计算后,合并的新 DataFrame 里。


例6:使用pd.Grouper分组

  • 例6-1、构建演示数据并观察数据内容
from datetime import datetimeimport numpy as np
import pandas as pd# 创建一个包含时间序列的DataFrame
date_rng = pd.date_range(start="2022-01-01", end="2022-01-19", freq="D")
df = pd.DataFrame(date_rng, columns=["date"])# 添加一列随机数值
df["value"] = np.random.randn(len(date_rng))# 观察数据内容
df
datevalue
02022-01-010.632771
12022-01-021.218292
22022-01-03-0.864251
32022-01-040.628204
42022-01-05-0.625454
52022-01-061.021081
62022-01-070.685509
72022-01-081.096754
82022-01-09-1.131979
92022-01-100.384067
102022-01-110.447377
112022-01-120.005861
122022-01-131.126507
132022-01-14-0.153360
142022-01-150.447708
152022-01-160.470841
162022-01-17-1.143815
172022-01-18-0.407859
182022-01-190.308274
  • 例6-2、构建以‘周’为周期的grouper对象,并观察其数据内容
# 创建grouper对象
grouper = pd.Grouper(key="date", freq="W")
grouper
TimeGrouper(key='date', freq=<Week: weekday=6>, axis=0, sort=True, dropna=True, closed='right', label='right', how='mean', convention='e', origin='start_day')
  • 例6-3、按周进行分组,求每周的均值
# 按轴分组,并计算每组的均值
result = df.groupby(grouper).mean()
result
value
date
2022-01-020.925532
2022-01-090.115695
2022-01-160.389857
2022-01-23-0.414467


例7:by参数传递列名列表,构成多层索引,作为多维度的数据汇总

  • 例7-1、构建演示数据并观察数据内容
import pandas as pd# 读取一个演示文件
df = pd.read_excel("../../../../数据集/团队成员日销售额.xlsx")# 只保留需要的列
df = df[["职级", "片区", "业绩"]]# 观察数据内容
df.sample(5)
职级片区业绩
82经理华中14494.9
14经理华南27318.5
67组长华东843.3
22经理华南853.8
43组长华北545.8
  • 例7-2、传递列名列表,多维度数据分组汇总。观察各职级销售人员,在不同地区的销售表现
df.groupby(by=["职级", "片区"]).sum()
业绩
职级片区
组长华东17526.0
华中4043.1
华北6524.8
经理华东148805.5
华中125646.0
华北58211.8
华南1067600.6
销售员华东7896.9
华中11233.6
华北1772.2
华南8281.1


例8:先转置再分割,实现类似纵向分割 axis=1 的效果

  • 例8-1、读取演示数据并观察内容
import pandas as pd# 读取一个演示文件
df = pd.read_excel("../../../../数据集/团队成员日销售额_用于转置.xlsx")# 观察数据内容
df
Unnamed: 0012345678...90919293949596979899
0职级销售员经理经理销售员销售员销售员销售员销售员销售员...经理经理销售员组长销售员销售员销售员经理销售员销售员
1片区华南华南华南华南华南华南华南华南华南...华中华中华中华中华中华中华中华中华中华中
2业绩523.916647.5825896.91051.1672.51542.2540.9752.5585...18261808968251112.9888.7721.3941.317740.2692.11165.2

3 rows × 101 columns

可以发现,在这个演示数据中,如果需要分组,则需要 axis=1 , 但是这不符合Pandas新版本特性。

  • 例8-2、先转置,再用片区分组
df.T.groupby(by=1).max()
02
1
华东销售员99327.4
华中销售员18261
华北销售员9388
华南销售员825896.9
片区职级业绩

分组完毕,by=1 是因为片区的哪一列,此时列名就是1


例9:多层索引需要使用 level 参数传递层级信息指定分组依据

  • 例9-1、读取演示数据,构建多层索引,观察数据内容
import pandas as pd# 读取一个演示文件
df = pd.read_excel("../../../../数据集/团队成员日销售额.xlsx")# 只保留需要的列
df = df[["职级", "片区", "业绩"]]# 构建多层索引
df.set_index(["片区", "职级"], inplace=True)# 观察数据内容
df.sample(5)
业绩
片区职级
华中经理1459.4
华南销售员540.9
销售员773.4
华中经理744.0
组长1304.8

  • 例9-2、 只使用片区作为分组依据,则只需要传递层级编号,或层级名称即可。
df.groupby(level="片区").sum()
业绩
片区
华东174228.4
华中140922.7
华北66508.8
华南1075881.7
df.groupby(level=0).sum()
业绩
片区
华东174228.4
华中140922.7
华北66508.8
华南1075881.7

  • 例9-3、 如果需要使用多列内容,使用列表传递层级编号或层级名称即可(可以混用)
df.groupby(level=[0, "职级"]).sum()
业绩
片区职级
华东组长17526.0
经理148805.5
销售员7896.9
华中组长4043.1
经理125646.0
销售员11233.6
华北组长6524.8
经理58211.8
销售员1772.2
华南经理1067600.6
销售员8281.1


例10:分组名称不再作为索引,使用SQL风格展示分组后的数据

import pandas as pd# 读取一个演示文件
df = pd.read_excel("../../../../数据集/团队成员日销售额.xlsx")# 只保留需要的列
df = df[["职级", "片区", "业绩"]]df
# 用片区进行分组,并关闭索引返回
df.groupby(by="片区", as_index=False).max()
片区职级业绩
0华东销售员99327.4
1华中销售员18261.0
2华北销售员9388.0
3华南销售员825896.9

由上面结果可以发现,片区列,没有再作为行索引。


例11:sort参数对分组结果的影响

  • 例11-1、默认情况下,数据分组后输出的 DataFrame 会开启组名排序
import pandas as pd# 构建演示数据
df = pd.DataFrame({"cat": ["b", "b", "a", "a"], "value": [1, 3, 2, 4]})# 用cat列构建分组,保持分组名排序开启,
grouped = df.groupby(by="cat").mean()
grouped
value
cat
a3.0
b2.0
  • 例11-2、 当 sort=False 数据分组后输出的 DataFrame 不再对组名排序
# 用cat列构建分组,关闭分组名排序
grouped2 = df.groupby(by="cat", sort=False).mean()
grouped2
value
cat
b2.0
a3.0


例12:应用apply,如果结果行数 > 分组数量,则无法完成汇总,各分组的行索引(组键)会和分组名组成多层索引

  • 例12-1、首先来观察以下,各个分组的行索引
import pandas as pd# 构建演示数据
df = pd.DataFrame({"cat": ["b", "b", "a", "a"], "value": [1, 3, 2, 4]})# 用cat列构建分组,保持分组名排序开启,
grouped = df.groupby(by="cat")# 打印每个组的内容
for name, group in grouped:print(f"Group {name}:")print(group)print("\n")
Group a:cat  value
2   a      2
3   a      4Group b:cat  value
0   b      1
1   b      3

留意上面结果,a和b两个分组的行索引2、3、0、1。

  • 例12-2、当 调用 apply ,但是结果行数 > 分组数量时,会产生由分组名、各分组行索引构成的多层索引,
import pandas as pd# 构建演示数据
df = pd.DataFrame({"cat": ["b", "b", "a", "a"], "value": [1, 3, 2, 4]})
# df['cat'] = df['cat'].astype('category')# 用cat列构建分组,保持分组名排序开启,
grouped = df.groupby(by="cat").apply(lambda x: x)
grouped
catvalue
cat
a2a2
3a4
b0b1
1b3

  • 例12-3、 当 group_keys=False 时,分组的键不会作为索引,而是返回一个不带有分组键的普通 DataFrame(或者 Series)。
import pandas as pd# 构建演示数据
df = pd.DataFrame({"cat": ["b", "b", "a", "a"], "value": [1, 3, 2, 4]})
# df['cat'] = df['cat'].astype('category')# 用cat列构建分组,保持分组名排序开启,
grouped = df.groupby(by="cat", group_keys=False).apply(lambda x: x)
grouped
catvalue
0b1
1b3
2a2
3a4
  • 例12-4、再来看一下,正常应该是什么样的
import pandas as pd# 构建演示数据
df = pd.DataFrame({"cat": ["b", "b", "a", "a"], "value": [1, 3, 2, 4]})
# df['cat'] = df['cat'].astype('category')# 用cat列构建分组,保持分组名排序开启,
grouped = df.groupby(by="cat").apply(lambda x: x.mean())
grouped
value
cat
a3.0
b2.0


例13:组键(分组名、或可理解为结果的行索引、也可以理解为各分组的行索引)缺失值处理

  • 例13-1 构建演示数据并观察
import pandas as pd# 构建演示数据
l = [["a", 12, 12], [None, 12.3, 33.0], ["b", 12.3, 123], ["a", 1, 1]]
df = pd.DataFrame(l, columns=["a", "b", "c"])df
abc
0a12.012.0
1None12.333.0
2b12.3123.0
3a1.01.0

  • 例13-2 在分组完成时,默认就已经舍弃了缺失值
grouped = df.groupby(by="a")# 打印每个组的内容
for name, group in grouped:print(f"Group {name}:")print(group)print("\n")
Group a:a     b     c
0  a  12.0  12.0
3  a   1.0   1.0Group b:a     b      c
2  b  12.3  123.0

由上面结果可以发现,当完成分组的时候,就已经没有缺失值了,这一步发生在合并每个分组产生结果之前。

  • 例13-3 dropna=True 可以保留缺失值
grouped = df.groupby(by="a", dropna=False).mean()
grouped
bc
a
a6.56.5
b12.3123.0
NaN12.333.0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/627941.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机组成原理 运输层

文章目录 运输层运输层协议概述进程之间的通信运输层的两个主要协议运输层的端口 用户数据报协议 UDPUDP 概述UDP 的首部格式 传输控制协议 TCP 概述TCP 最主要的特点TCP 的连接 可靠传输的工作原理停止等待协议连续 ARQ协议 TCP 报文段的首部格式TCP 可靠传输的实现以字节为单…

TensorRT模型优化部署 (八)--模型剪枝Pruning

系列文章目录 第一章 TensorRT优化部署&#xff08;一&#xff09;–TensorRT和ONNX基础 第二章 TensorRT优化部署&#xff08;二&#xff09;–剖析ONNX架构 第三章 TensorRT优化部署&#xff08;三&#xff09;–ONNX注册算子 第四章 TensorRT模型优化部署&#xff08;四&am…

Go-安装与基础语法

TOC 1. Go 安装与环境变量 1.1 下载 需要从Go语言的官方网站下载适合你操作系统的Go语言安装包。Go语言支持多种操作系统&#xff0c;包括Windows、Linux和Mac OS。 对于Windows用户&#xff0c;下载.msi文件&#xff0c;然后双击该文件&#xff0c;按照提示进行安装即可。…

python的装饰器详解

目录 一&#xff1a;介绍 二&#xff1a;在方法中使用 三&#xff1a;在类中使用 四&#xff1a;python自带的装饰器 一&#xff1a;介绍 Python的装饰器是一种高阶函数&#xff0c;它允许你在不改变函数内部逻辑的情况下&#xff0c;给函数添加额外的功能。装饰器本质上是…

【C++进阶】心心念念的红黑树,它来了!

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;C航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1…

Spring框架是如何解决Bean创建过程中的循环依赖问题的

引言 本文主要梳理了Spring框架Bean创建过程中应对循环依赖问题的相关源码。我在手写super-mini-webpackhttps://blog.csdn.net/q1424966670/article/details/135628531?spm1001.2014.3001.5502的时候也介绍过解决循环依赖的算法&#xff1a;Map记忆化搜索。可以猜测这段源码…

ACL【新华三与华为的区别】

【解释】acl简单点解释就是&#xff0c;一套根据需求而设置的规则 【背景】 192.168.1.0/24 网段不允许访问 192.168.2.0/24 网段&#xff0c;要求使用基本 ACL 实现20_1 可以访问 20_6 的 TELNET 服务&#xff0c;但不能访问 FTP 服务 【操作步骤】 {易混点 }&#xff1a;1. …

机器学习周刊第六期:哈佛大学机器学习课、Chatbot Ul 2.0 、LangChain v0.1.0、Mixtral 8x7B

— date: 2024/01/08 — 吴恩达和Langchain合作开发了JavaScript 生成式 AI 短期课程&#xff1a;《使用 LangChain.js 构建 LLM 应用程序》 大家好&#xff0c;欢迎收看第六期机器学习周刊 本期介绍10个内容&#xff0c;涉及Python、机器学习、大模型等,目录如下&#xff…

Miracast手机高清投屏到电视(免费)

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl Miracast概述 Miracast是一种无线显示标准&#xff0c;它允许支持Miracast的设备之间通过Wi-Fi直接共享音频和视频内容&#xff0c;实现屏幕镜像或扩展显示。这意味着你可以…

C++常用类

1、QString 字符串类 QString 是Qt的字符串类&#xff0c;与C的std::string相比&#xff0c;不再使用ASCII编码。QString使用的Unicode编码。 QString 完全支持中文&#xff0c; 但是由于不同的技术可能会采用不同的编码。有时候也会遇到中文编码的一致性问题。 如果后续的学习…

PointMixer: MLP-Mixer for Point Cloud Understanding

Abstract MLP-Mixer 最近崭露头角,成为对抗CNNs和Transformer领域的新挑战者。尽管相比Transformer更为简单,但通道混合MLPs和令牌混合MLPs的概念在图像识别任务中取得了显著的性能。与图像不同,点云本质上是稀疏、无序和不规则的,这限制了直接将MLP-Mixer用于点云理解。为…

i18n多国语言Internationalization的实现

i18n 是"Internationalization”的缩写&#xff0c;这个术语来源于英文单词中首尾字母“”和“n”以及中间的字符数(共计18个字符) 当我们需要开发不同语言版本时&#xff0c;就可以使用i18n多国语言的一个操作处理&#xff0c;i18n主要实现那一方面的内容呢&#xff1f;…

项目压测优化实践思路

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring原理、JUC原理、Kafka原理、分布式技术原理、数据库技术&#x1f525;如果感觉博主的文章还不错的…

日本樱岛火山喷发遥感卫星影像监测

日本樱岛火山喷发监测 当地时间2024年1月9日15时许&#xff0c;位于日本九州地区鹿儿岛县的樱岛南岳山顶火山口&#xff0c;开始喷发&#xff0c;火山烟雾从火山口上升至空中1200米左右。目前&#xff0c;日本气象厅将樱岛的火山警戒级别维持在3级&#xff0c;限制民众入山。 火…

HCS私有云简介

1、HCS简介和发展史 华为云产品&#xff1a;私有云和公有云&#xff0c;现在的私有云已经和公有云越来越像了FusionSphere是华为的一个品牌2016年&#xff0c;在5.0版本的时候&#xff0c;华为Openstack叫FusionSphere Openstack 5.0&#xff0c;底层用的是suse操作系统&#…

BitLocker 驱动器加密

BitLocker 简介 BitLocker 驱动器加密是一项由微软开发并集成在Windows操作系统中的数据保护功能&#xff0c;其主要作用是通过加密存储在硬盘驱动器上的数据来增强信息安全。具体来说&#xff1a; 数据安全&#xff1a;BitLocker可以对整个操作系统卷&#xff08;包括系统分区…

开源图床Lychee本地如何部署并结合内网穿透工具实现远程访问

文章目录 1.前言2. Lychee网站搭建2.1. Lychee下载和安装2.2 Lychee网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4.公网访问测试5.结语 1.前言 图床作为图片集中存放的服务网站&#xff0c;可以看做是云存储的一部分&#xff0c;既可…

酒店订房小程序源码系统:帮您打造类似美团的酒店模式的小程序 带完整的安装部署教程

随着移动互联网的快速发展&#xff0c;小程序已经成为一种新型的应用形态&#xff0c;为各大行业提供了更加便捷的服务。其中&#xff0c;酒店预订小程序作为一种方便快捷的预订方式&#xff0c;备受用户青睐。小编给大家分享一款酒店订房小程序源码系统&#xff0c;旨在帮助您…

中霖教育:中级会计师报名条件是什么?

一、学历要求 报考中级会计师的考生需要具备大专及以上学历&#xff0c;如果不满足学历要求是无法报考的。 二、工作经验要求 报考中级会计师的考生需要具备一定的工作经验。根据规定&#xff0c;不同的学历对从业年限要求不同&#xff0c;主要有以下几种情况&#xff1a; …

多租户体系实现

文章目录 核心思路方案选择设计考量安全性扩展性通用性易用性 具体实现租户信息透传透传变量名命名规范应用内透传应用间透传 数据层租户隔离MySQL存储方案&#xff1a;多租户Mybatis插件Mybatis插件特点使用多租户Mybatis插件的优势参考文档 应用场景 经过工作中的一处场景启发…