Datawhale-Pandas中文教程[4]

分组模式及其对象

分组操作应用非常广泛:

  • 依据 性别分组,统计 _学生身高_的中位数
  • 依据 季节分组,对每个季节的 _温度_进行组内标准化
  • 依据 班级分组,筛选组内 _数学分数_的平均值超过80分的班级

想要实现分组操作,必须明确三个要素: 分组依据数据来源、操作及其返回结果。
df.groupby(分组依据)[数据来源].使用操作

df = pd.read_csv('data/learn_pandas.csv')
df.groupby('Gender')['Height'].median()
根据学校和性别进行分组,统计身高的均值
df.groupby(['School', 'Gender'])['Height'].mean()

如果需要根据多个维度进行分组,只需要在groupby中的 分组依据中传入相应列名构成的列表即可。
分组依据可以直接从列中按照名字获取。如果希望通过一定的复杂逻辑来分组,可以先写出分组条件,再将其传入 groupby

根据学生体重是否超过总体均值来分组
condition = df.weight > df.weight.mean()
df.groupby(condition)['Height'].mean()
根据上下四分位数分割,将体重分为high, normal, low三组,统计身高的均值
def my_group(x):
     if x <= df.weight.quantile(0.25): return('low') if x>= df.Weight.quantile(0.75):
         return('high')
     else:
         return('normal')
condition = df.Weight.apply(my_groupby)
df.groupby(condition)['Height].mean()
</=>

groupby方法最后产生的结果就是按照 分组依据中元素的值(可以是布尔,可以是[‘low’,’high’,’normal’],’abc’等)来分组,例如上面和下面这个例子。(感觉也像根据自己给定的索引来分组)

my_series = np.random.choice(list('abc'), df.shape[0])
df.groupby(my_series)['Height'].mean()

如果传入多个序列进入 groupby, 最后分组的依据就是对这两个序列对应行的唯一组合。通过 drop_duplicates()方法能够知道来自于 _数据来源_组合的unique值,也就是具体的组类别,后面的 groupby中的 groups属性也能完成类似的功能

&#x4F20;&#x5165;&#x591A;&#x4E2A;&#x5E8F;&#x5217;&#x8FDB;&#x5165;groupby
df.groupby([condition, my_series])['Height'].mean()
&#x6765;&#x81EA;&#x4E0D;&#x540C;&#x5B66;&#x6821;&#x7684;&#x7537;&#x751F;&#x548C;&#x5973;&#x751F;&#x7684;&#x8EAB;&#x9AD8;&#x5E73;&#x5747;&#x503C;
df.groupby([df['School'], df['Gender']])['Height'].mean()
gb = df.groupby(['School', 'Grade'])
print(gb)
<pandas.core.groupby.generic.dataframegroupby object at 0x000001cbc8be6220>
</pandas.core.groupby.generic.dataframegroupby>

具体做分组操作时,所调用的方法都来自于 pandas 中的 groupby对象,这个对象上定义了许多方法,也具有一些方便的属性。

  • ngroups属性:得到分组个数
  • groups属性:返回从组名映射到组索引列表的字典(字典的键是组合形成的元组列表,值是相应的元素在原表中的索引)
res = gb.groups
res.keys()
res[('Fudan University', 'Freshman')]
-> Int64Index([15, 28, 63, 70, 73, 105, 108, 157, 186], dtype='int64')
&#x8868;&#x793A;&#x539F;&#x8868;&#x4E2D;&#x7B2C;15&#xFF0C;28&#xFF0C;...&#x4E2A;&#x7684;&#x5B66;&#x751F;&#xFF0C;School&#x662F;&#x590D;&#x65E6;&#xFF0C;Grade&#x662F;Freshman
  • size: 返回每个组的元素个数,作为 DataFrame的属性时返回的是表长乘以表宽的大小
  • get_group方法:直接获取所在组对应的行,此时必须知道组的具体名字,返回的是DataFrame
gb.get_group(('Fudan University', 'Freshman')).iloc[:3, :3]
&#x5C55;&#x793A;&#x524D;&#x4E09;&#x884C;&#x524D;&#x4E09;&#x5217;
  • mean, median等(待补充

熟悉了一些分组的基本知识后,重新回到开头举的三个例子,可能会发现一些端倪,即这三种类型分组返回的数据型态并不一样:
第一个例子中,每一个组返回一个标量值,可以是平均值、中位数、组容量 size 等
第二个例子中,做了原序列的标准化处理,也就是说每组返回的是一个 Series 类型
第三个例子中,既不是标量也不是序列,返回的整个组所在行的本身,即返回了 DataFrame 类型
由此引申出了分组的三大操作

  • agg: 操作
  • transform: 变换
  • filter: 过滤

使用聚合功能时应当优先考虑直接定义在groupby对象的聚合函数,因为它的速度基本都会经过内部的优化。
聚合函数返回标量值,包括:
max/min/mean/median/count/all/any /idxmax/idxmin/mad/nunique/skew /quantile/sum/std/var/sem/size/prod
这些函数顾名思义已经比较清楚了,不清楚的可以去查阅pandas官方文档。且这些聚合函数当传入的数据来源包含多个列时,将按照列进行迭代计算

groupby对象上定义的内置聚合函数有以下的缺点:无法同时使用多个函数、无法对特定的列使用特定的聚合函数、无法使用自定义的聚合函数、无法直接对结果的列名在聚合前进行自定义命名

变换函数的返回值为同长度的序列。
常用的内置变换函数有累计函数 cumcount, cumsum, cumprod, cummax, cummin,其使用方式和聚合函数类似,只不过完成的是组内累计操作。
groupby对象上填充类和滑窗类的变换函数将在第七章和第十章中讨论。
cumcount:

GroupBy.cumcount(ascending: bool = True)
&#x7B49;&#x4EF7;&#x4E8E; self.apply(lambda x: pd.Series(np.arange(len(x)), x.index))
&#x4F5C;&#x7528;&#x662F;&#x7ED9;&#x5206;&#x7EC4;&#x7684;&#x7EC4;&#x5185;&#x5404;&#x4E2A;&#x9879;&#x76EE;&#x8FDB;&#x884C;&#x7F16;&#x53F7;
df = pd.DataFrame([['a'], ['a'], ['a'], ['b'], ['b'], ['a']],
                  columns=['A'])
df.groupby('A').cumcount()
df.groupby('A').cumcount(ascending=False)
&#x53C2;&#x6570;&#x4E3A;False&#x6CA1;&#x592A;&#x641E;&#x660E;&#x767D;

cumsum:

https://blog.csdn.net/qq_22238533/article/details/72900634?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-72900634-blog-79472875.t5_download_all&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-72900634-blog-79472875.t5_download_all&utm_relevant_index=1

cummax: gb.cummax().head()
rank:

DataFrame&#x7B49;&#x6570;&#x636E;&#x7ED3;&#x6784;&#x4E5F;&#x6709;rank&#x65B9;&#x6CD5;
#

transform方法:被调用的自定义函数传入值为数据源的序列,与 agg的传入类型是一致的,其最后的返回结果是行列索引与数据源一致的 DataFrame

&#x5BF9;&#x8EAB;&#x9AD8;&#x548C;&#x4F53;&#x91CD;&#x8FDB;&#x884C;&#x5206;&#x7EC4;&#x6807;&#x51C6;&#x5316;
&#x5373;&#x51CF;&#x53BB;&#x7EC4;&#x5747;&#x503C;&#x540E;&#x9664;&#x4EE5;&#x7EC4;&#x7684;&#x6807;&#x51C6;&#x5DEE;
gb.transform(lambda x: (x-x.mean())/x.std()).head()

transform只能返回同长度的序列,但事实上还可以返回一个标量,这会使得结果被广播到其所在的整个组,这种 标量广播 的技巧在特征工程中是非常常见的。

&#x6784;&#x9020;&#x4E24;&#x5217;&#x65B0;&#x7279;&#x5F81;&#x6765;&#x5206;&#x522B;&#x8868;&#x793A;&#x6837;&#x672C;&#x6240;&#x5728;&#x6027;&#x522B;&#x7EC4;&#x7684;&#x8EAB;&#x9AD8;&#x5747;&#x503C;&#x548C;&#x4F53;&#x91CD;&#x5747;&#x503C;
gb.transform('mean').head() # &#x4F20;&#x5165;&#x8FD4;&#x56DE;&#x6807;&#x91CF;&#x7684;&#x51FD;&#x6570;&#x4E5F;&#x662F;&#x53EF;&#x4EE5;&#x7684;

索引和过滤的区别:过滤在分组中是对于组的过滤,而索引是对于行的过滤(行过滤),在第二章中的返回值,无论是布尔列表还是元素列表或者位置列表,本质上都是对于行的筛选,即如果符合筛选条件的则选入结果表,否则不选入。
组过滤作为索引(行过滤)的推广,指的是如果对一个组的全体所在行进行统计的结果返回 True则会被保留, False则该组会被过滤,最后把所有未被过滤的组其对应的所在行拼接起来作为 DataFrame返回。
groupby对象中,定义了 filter方法进行组的筛选,其中自定义函数的输入参数为数据源构成的 DataFrame本身,在之前例子中定义的 groupby对象中,传入的就是 df[['Height', 'Weight']],因此所有表方法和属性都可以在自定义函数中相应地使用,同时只需保证自定义函数的返回为布尔值即可。

&#x5728;&#x539F;&#x8868;&#x4E2D;&#x901A;&#x8FC7;&#x8FC7;&#x6EE4;&#x5F97;&#x5230;&#x6240;&#x6709;&#x5BB9;&#x91CF;&#x5927;&#x4E8E;100&#x7684;&#x7EC4;
gb.filter(lambda x: x.shape[0] > 100).head()

之前几节介绍了三大分组操作,但事实上还有一种常见的分组场景,无法用前面介绍的任何一种方法处理:
定义身体质量指数BMI:
B M I = W e i g h t H e i g h t 2 {\rm BMI} = {\rm\frac{Weight}{Height^2}}BMI =Heigh t 2 Weight ​
其中体重和身高的单位分别为千克和米,需要分组计算组BMI的均值

#
def BMI(x):
    Height = x['Height']/100
    Weight = x['Weight']
    BMI_value = Weight/Height**2
    return BMI_value.mean()
gb.apply(BMI)

首先,这不是过滤操作,因此 filter不符合要求;其次,返回的均值是标量而不是序列,因此 transform不符合要求;最后,似乎使用 agg函数能够处理,但是之前强调过聚合函数是逐列处理的,而不能够多列数据同时处理 。由此,引出了 apply函数来解决这一问题。
除了返回标量之外, apply 方法还可以返回一维 Series 和二维 DataFrame

待补充

待补充

Original: https://blog.csdn.net/qq_48633796/article/details/126607844
Author: 少喝奶茶qaq
Title: Datawhale-Pandas中文教程[4]

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/742593/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 【数据分析】Numpy学习笔记(一)

    最近在学习数据分析,到了numpy的学习阶段,边学边整理分享自己的学习笔记,希望能对你也有所帮助!这次的学习笔记包括以下内容:1.数组的创建方式2.多维数组的简单操作3.数组的索引…

    Python 2023年8月25日
    070
  • 几个常用的Numpy函数详解

    Numpy是python中最有用的工具之一。它可以有效地处理大容量数据。使用NumPy的最大原因之一是它有很多处理数组的函数。在本文中,将介绍NumPy在数据科学中最重要和最有用的…

    Python 2023年8月28日
    067
  • Java深度学习库DJL实现Python的NumPy

    目录 1 NDArray 的背景介绍 * 1.1 架构 2 JavaDJL使用 * 2.1 安装DJL 2.2 基本操作 2.3 创建NDArray 2.4 数学运算 2.5 Ge…

    Python 2023年8月28日
    052
  • pandas 构造序列

    list_1=[[100,200],200,300]dict_1={‘x’:100,’y’:200,’z’:…

    Python 2023年8月8日
    055
  • Flask-AppBuilder中用babel统一管理提示信息

    不仅仅flask-appbuilder甚至是flask的开发过程中会在代码中写死很多提示信息如”输入错误”、该页面不存在等等,一开始对babel支持多语言的…

    Python 2023年8月13日
    036
  • Scrapy框架爬虫实战——从入门到放弃02

    Scrapy框架爬虫实战02——以猎云网为例的CrawlSpider爬虫 建议在看过第一篇Scrapy框架实战并顺利运行其中的代码后,再看这一篇实战。第一篇链接:传送门 文章目录 …

    Python 2023年10月5日
    059
  • Python数据库操作 —- pymysql教学

    文章目录 * – 前提准备 – 连接数据库 – 创建数据库 – 创建数据表、 – 插入数据 – 查询数据 &…

    Python 2023年11月6日
    038
  • three.js之组对象

    文章目录 简介 例子 查看组对象 组对象相关方法 * add remove 层级模型节点命名、查找、遍历 * 模型命名 例子 遍历 查找 本地坐标与世界坐标 * 例子 本地坐标 世…

    Python 2023年9月15日
    030
  • None 和 NaN分不清? pandas 难点彻底搞懂

    Pandas 和 Numpy 是数据挖掘和数据科学中广泛使用的工具,但有时人们会对 None 和 NaN 感到困惑,它们非常相似但略有不同的数据类型。 在这里,我们通过一些示例彻底…

    Python 2023年8月18日
    051
  • Shell揭秘——程序退出状态码

    程序退出状态码 前言 在本篇文章当中主要给大家介绍一个shell的小知识——状态码。这是当我们的程序退出的时候,子进程会将自己程序的退出码传递给父进程,有时候我们可以利用这一操作做…

    Python 2023年10月18日
    069
  • 使用 Anaconda 安装 Pytorch

    PyTorch介绍:PyTorch是一个开源的Python机器学习库,基于Torch,用于自然语言处理等应用程序。其运行环境已兼容Windows (CUDA,CPU)、MacOS …

    Python 2023年8月1日
    055
  • Pandas库常用命令汇总——自用备查(挖坑,持续更新)

    目录 引入库(数据分析常用三件套) 读取文件(excel、csv) 查看数据集 填充缺失值 查看,截取(切片)数据集 分组:groupby命令 聚合:agg命令 聚合:transf…

    Python 2023年8月22日
    048
  • 听说你想面对监狱编程,你,够格吗?

    先说明一下,我的这篇文章没有太多的技术含量,最多只有一些的技术总结,剩下的是我这几个月算是自身经历吧,但是没跑题啊,还是跟爬虫技术的先关的,不喜欢可以关了哈,来都来了就看看呗,没准…

    Python 2023年8月1日
    062
  • DOS中切换盘符(直接CD不行),直接切换到其他盘的目录

    切换盘符: c:\>d: 直接切换到其他盘的目录: 直接cd是不行的,还要加上参数 /d &#x4F8B;&#x5982;&#x5F53;&#…

    Python 2023年11月6日
    037
  • NumPy创建区间数组

    所谓区间数组,是指数组元素的取值位于某个范围内,并且数组元素之间可能会呈现某种规律,比如等比数列、递增、递减等。 为了方便科学计算,Python NumPy 支持创建区间数组。 1…

    Python 2023年8月26日
    037
  • 【Pytorch】torch.nn.init.xavier_uniform_()

    目录 简介 torch.nn.init.xavier_uniform_() * 语法 作用 举例 参考 结语 ; 简介 Hello!非常感谢您阅读海轰的文章,倘若文中有错误的地方,…

    Python 2023年11月5日
    047
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球