Python数据分析NumPy和pandas(三十一、数据聚合)

聚合是指从数组生成标量值的数据转换。上一次学习的代码示例使用了其中几个聚合函数,包括 mean、count、min 和 sum。常见的聚合见下图列表,但是,不仅限于列表中的这组方法。在 GroupBy 对象上调用聚合函数(例如: mean) 时会发生了什么,下面会学习了解。

可以使用自己的设计的聚合方法,也可以调用分组的对象上定义的任何方法。

以上次学习记录中的DataFrame对象df作为操作数据开始学习:

import numpy as np
import pandas as pdnp.random.seed(12345)
df = pd.DataFrame({"key1" : ["a", "a", None, "b", "b", "a", None],"key2" : pd.Series([1, 2, 1, 2, 1, None, 1], dtype="Int64"),"data1" : np.random.standard_normal(7),"data2" : np.random.standard_normal(7)})print(df)

df输出:

key1key2data1data2
0a1-0.2047080.281746
1a20.4789430.769023
2None1-0.5194391.246435
3b2-0.5557301.007189
4b11.965781-1.296221
5a<NA>1.3934060.274992
6None10.092908

0.228913

下面对df按键key1进行切片,然后对每个切片调用nsmallest(求最小值),并将结果组装到最后的结果对象中:

import numpy as np
import pandas as pdnp.random.seed(12345)
df = pd.DataFrame({"key1" : ["a", "a", None, "b", "b", "a", None],"key2" : pd.Series([1, 2, 1, 2, 1, None, 1], dtype="Int64"),"data1" : np.random.standard_normal(7),"data2" : np.random.standard_normal(7)})grouped = df.groupby("key1")
result = grouped["data1"].nsmallest(2)
print(result)

输出结果:

我们可以使用自己定义的聚合函数,使用方法是将函数传递给 aggregate() 方法或它的短别名 agg()方法,例如:

import numpy as np
import pandas as pd# 自定义聚合函数,返回数组或列表中最大值和最小值的差
def max_to_min(arr):return arr.max() - arr.min()np.random.seed(12345)
df = pd.DataFrame({"key1" : ["a", "a", None, "b", "b", "a", None],"key2" : pd.Series([1, 2, 1, 2, 1, None, 1], dtype="Int64"),"data1" : np.random.standard_normal(7),"data2" : np.random.standard_normal(7)})grouped = df.groupby("key1")
result = grouped.agg(max_to_min)
print(result)

输出结果:

key2data1data2
key1
a11.5981130.494031
b12.5215112.303410

我们会发现,虽然一些统计描述方法严格上来说不是聚合函数,但是也可以使用(如 describe): 

import numpy as np
import pandas as pd# 自定义聚合函数,返回数组或列表中最大值和最小值的差
def max_to_min(arr):return arr.max() - arr.min()np.random.seed(12345)
df = pd.DataFrame({"key1" : ["a", "a", None, "b", "b", "a", None],"key2" : pd.Series([1, 2, 1, 2, 1, None, 1], dtype="Int64"),"data1" : np.random.standard_normal(7),"data2" : np.random.standard_normal(7)})grouped = df.groupby("key1")
result = grouped.describe()
print(result)

输出结果:

key2data1data2
countmeanstdmin25%50%75%maxcountmean...75%maxcountmeanstdmin25%50%75%max
key1
a2.01.50.7071071.01.251.51.752.03.00.555881...0.9361751.3934063.00.4419200.2832990.2749920.2783690.2817460.5253840.769023
b2.01.50.7071071.01.251.51.752.02.00.705025...1.3354031.9657812.0-0.1445161.628757-1.296221-0.720368-0.1445160.4313371.007189

2 rows × 24 columns

注意:自定义聚合函数通常比上面列表中的优化函数慢得多。这是因为在构建中间组数据块时有一些额外的开销(函数调用、数据重新排列)。

按列进行聚合统计操作

使用上次的tip.csv文件中的数据,还是用代码示例学习更直观:

import numpy as np
import pandas as pdtips = pd.read_csv("examples/tips.csv")
# 输出tips.csv前5行数据
print(tips.head())# 给tips添加一列tip_pct,这一列数据是小费占该次消费金额的百分比
tips["tip_pct"] = tips["tip"] / tips["total_bill"]
# 输出添加tip_pct列后的前5行
print(tips.head())# 按日期和吸烟者对tips进行分组
grouped = tips.groupby(["day", "smoker"])
grouped_pct = grouped["tip_pct"]result = grouped_pct.agg("mean")
print(result)

以上代码按day和smoker列名进行分组,并用agg传递聚合函数mean求每个组的小费百分比的平均值,输出结果:

如果我们传给agg一个聚合函数名称的列表,最后结果会输出一个DataFrame,列名称是函数名,例如:

import numpy as np
import pandas as pd# 自定义聚合函数,返回数组或列表中最大值和最小值的差
def max_to_min(arr):return arr.max() - arr.min()tips = pd.read_csv("examples/tips.csv")
# 输出tips.csv前5行数据
print(tips.head())# 给tips添加一列tip_pct,这一列数据是小费占该次消费金额的百分比
tips["tip_pct"] = tips["tip"] / tips["total_bill"]
# 输出添加tip_pct列后的前5行
print(tips.head())# 按日期和吸烟者对tips进行分组
grouped = tips.groupby(["day", "smoker"])
grouped_pct = grouped["tip_pct"]result = grouped_pct.agg(["mean", "std", max_to_min])
print(result)

输出结果:

meanstdmax_to_min
daysmoker
FriNo0.1516500.0281230.067349
Yes0.1747830.0512930.159925
SatNo0.1580480.0397670.235193
Yes0.1479060.0613750.290095
SunNo0.1601130.0423470.193226
Yes0.1872500.1541340.644685
ThurNo0.1602980.0387740.193350
Yes0.1638630.0393890.151240

我们也可以传递一个 (name, function) 元组列表,每个元组的第一个元素将用作 DataFrame 列名(可以将 2 元组的列表视为有序映射) ,例如:

import numpy as np
import pandas as pdtips = pd.read_csv("examples/tips.csv")
# 输出tips.csv前5行数据
print(tips.head())# 给tips添加一列tip_pct,这一列数据是小费占该次消费金额的百分比
tips["tip_pct"] = tips["tip"] / tips["total_bill"]
# 输出添加tip_pct列后的前5行
print(tips.head())# 按日期和吸烟者对tips进行分组
grouped = tips.groupby(["day", "smoker"])
grouped_pct = grouped["tip_pct"]result = grouped_pct.agg([("average", "mean"), ("stdev", "std")])
print(result)

输出结果:

averagestdev
daysmoker
FriNo0.1516500.028123
Yes0.1747830.051293
SatNo0.1580480.039767
Yes0.1479060.061375
SunNo0.1601130.042347
Yes0.1872500.154134
ThurNo0.1602980.038774
Yes0.1638630.039389

通过使用 DataFrame,我们可以指定要应用于所有列的函数列表或每个列的不同函数。再看一个里例子,假设我们要为 tip_pct 和 total_bill 列计算相同的三个统计信息,可以这样:

import numpy as np
import pandas as pdtips = pd.read_csv("examples/tips.csv")
# 输出tips.csv前5行数据
print(tips.head())# 给tips添加一列tip_pct,这一列数据是小费占该次消费金额的百分比
tips["tip_pct"] = tips["tip"] / tips["total_bill"]
# 输出添加tip_pct列后的前5行
print(tips.head())# 按日期和吸烟者对tips进行分组
grouped = tips.groupby(["day", "smoker"])functions = ["count", "mean", "max"]result = grouped[["tip_pct", "total_bill"]].agg(functions)
print(result)

输出结果:

tip_pcttotal_bill
countmeanmaxcountmeanmax
daysmoker
FriNo40.1516500.187735418.42000022.75
Yes150.1747830.2634801516.81333340.17
SatNo450.1580480.2919904519.66177848.33
Yes420.1479060.3257334221.27666750.81
SunNo570.1601130.2526725720.50666748.17
Yes190.1872500.7103451924.12000045.35
ThurNo450.1602980.2663124517.11311141.19
Yes170.1638630.2412551719.19058843.11

如上输出,生成的 DataFrame 具有分层列,这与我们单独聚合每个列并使用 concat 将结果粘合在一起(使用列名作为 keys 参数)相同,我们单独将 result["tip_pct"]筛选出来看看:

countmeanmax
daysmoker
FriNo40.1516500.187735
Yes150.1747830.263480
SatNo450.1580480.291990
Yes420.1479060.325733
SunNo570.1601130.252672
Yes190.1872500.710345
ThurNo450.1602980.266312
Yes170.1638630.241255

和上面一样,可以传递具有自定义名称的 Tuples 列表:

import numpy as np
import pandas as pdtips = pd.read_csv("examples/tips.csv")
# 输出tips.csv前5行数据
print(tips.head())# 给tips添加一列tip_pct,这一列数据是小费占该次消费金额的百分比
tips["tip_pct"] = tips["tip"] / tips["total_bill"]
# 输出添加tip_pct列后的前5行
print(tips.head())# 按日期和吸烟者对tips进行分组
grouped = tips.groupby(["day", "smoker"])
ftuples = [("Average", "mean"), ("Variance", "var")]result = grouped[["tip_pct", "total_bill"]].agg(ftuples)
print(result)

输出结果:

tip_pcttotal_bill
AverageVarianceAverageVariance
daysmoker
FriNo0.1516500.00079118.42000025.596333
Yes0.1747830.00263116.81333382.562438
SatNo0.1580480.00158119.66177879.908965
Yes0.1479060.00376721.276667101.387535
SunNo0.1601130.00179320.50666766.099980
Yes0.1872500.02375724.120000109.046044
ThurNo0.1602980.00150317.11311159.625081
Yes0.1638630.00155119.19058869.808518

现在,如果我们想将不同的函数应用于一个或多个列,那我们可以传递一个字典给agg,其中字典包含的是列名称到函数的映射: 

import numpy as np
import pandas as pdtips = pd.read_csv("examples/tips.csv")
# 输出tips.csv前5行数据
print(tips.head())# 给tips添加一列tip_pct,这一列数据是小费占该次消费金额的百分比
tips["tip_pct"] = tips["tip"] / tips["total_bill"]
# 输出添加tip_pct列后的前5行
print(tips.head())# 按日期和吸烟者对tips进行分组
grouped = tips.groupby(["day", "smoker"])
result = grouped.agg({"tip" : "max", "size" : "sum"})
result2 = grouped.agg({"tip_pct" : ["min", "max", "mean", "std"], "size" : "sum"})
print(result, '\n', result2)

result输出结果:

tipsize
daysmoker
FriNo3.509
Yes4.7331
SatNo9.00115
Yes10.00104
SunNo6.00167
Yes6.5049
ThurNo6.70112
Yes5.0040

result2输出结果:

tip_pctsize
minmaxmeanstdsum
daysmoker
FriNo0.1203850.1877350.1516500.0281239
Yes0.1035550.2634800.1747830.05129331
SatNo0.0567970.2919900.1580480.039767115
Yes0.0356380.3257330.1479060.061375104
SunNo0.0594470.2526720.1601130.042347167
Yes0.0656600.7103450.1872500.15413449
ThurNo0.0729610.2663120.1602980.038774112
Yes0.0900140.2412550.1638630.03938940

 注意:仅当将多个函数应用于至少一列时,DataFrame 才会具有分层列。

返回不带行索引的聚合数据

在到目前为止的所有示例中,聚合数据都返回了一个索引,该索引可能是分层的,由唯一的组键组合而成。如果不需要索引,我们可以通过将 as_index=False 传递给 groupby 来禁用此行为:

import numpy as np
import pandas as pdtips = pd.read_csv("examples/tips.csv")# 给tips添加一列tip_pct,这一列数据是小费占该次消费金额的百分比
tips["tip_pct"] = tips["tip"] / tips["total_bill"]result = tips.groupby(["day", "smoker"], as_index=False).mean()
print(result)

输出结果:

daysmokertotal_billtipsizetip_pct
0FriNo18.4200002.8125002.2500000.151650
1FriYes16.8133332.7140002.0666670.174783
2SatNo19.6617783.1028892.5555560.158048
3SatYes21.2766672.8754762.4761900.147906
4SunNo20.5066673.1678952.9298250.160113
5SunYes24.1200003.5168422.5789470.187250
6ThurNo17.1131112.6737782.4888890.160298
7ThurYes19.1905883.0300002.3529410.163863

当然,通过对结果调用 reset_index 方法也可以实现去除索引,但是会需要一些计算,因此在分组的时候使用 as_index=False 参数可避免一些不必要的计算。 

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

公链数字钱包开发与加密钱包App原生开发

随着区块链技术的不断发展&#xff0c;数字货币和去中心化金融&#xff08;DeFi&#xff09;的兴起&#xff0c;公链数字钱包的需求日益增加。数字钱包不仅为用户提供存储、管理和交易数字资产的工具&#xff0c;而且也为区块链技术的应用提供了一个重要的入口。开发一个安全、…

0. 0:《跟着小王学Python·新手》

《跟着小王学Python新手》系列 《跟着小王学Python》 是一套精心设计的Python学习教程&#xff0c;适合各个层次的学习者。本教程从基础语法入手&#xff0c;逐步深入到高级应用&#xff0c;以实例驱动的方式&#xff0c;帮助学习者逐步掌握Python的核心概念。通过开发游戏、构…

HTTPTomcatServle之HTTP详解

✨博客主页&#xff1a; https://blog.csdn.net/m0_63815035?typeblog &#x1f497;《博客内容》&#xff1a;.NET、Java.测试开发、Python、Android、Go、Node、Android前端小程序等相关领域知识 &#x1f4e2;博客专栏&#xff1a; https://blog.csdn.net/m0_63815035/cat…

「数据要素」行业简报|2024.11.上刊

纵观数据要素行业动态&#xff0c;洞察行业风向&#xff0c;把握行业脉搏&#xff01; 一、政策发布 1、《山东省公共数据资源登记管理工作规范(试行)》公开征求意见 11月7日&#xff0c;为认真贯彻落实《中共中央办公厅 国务院办公厅关于加快公共数据资源开发利用的意见》《…

NFS Write IO 不对齐深度分析

背景 最近团队小伙伴弗曼统计了线上用户数据写入对齐情况&#xff0c;通过统计数据发现了一个有趣的现象: 用户写入请求中近 70% 的数据块 4K 不对齐&#xff0c;这也就是说 NFSClient 对大多数的应用写入没有做对齐优化。 下面会从 NFSClient BufferWrite 实现流程的维度解释…

微型导轨在自动化生产线中起什么作用?

在现代制造业的飞速跃进中&#xff0c;自动化生产线的蓬勃发展引领了一场效率与质量的双重革命。微型导轨作为传动领域的重要零部件&#xff0c;可用于工业自动化生产线上的零件运输、加工设备定位等&#xff0c;实现自动化生产和减少人力成本。那么&#xff0c;微型导轨在自动…

【ESP32】DIY一个电子测光仪

这里写目录标题 0 前言1 开箱2 过程2.1 下载固件2.2 烧录固件2.3 编程环境 Thonny2.4 点灯大师2.5 TFT屏幕2.6 BH1750传感器 成果展示 0 前言 开发板&#xff1a;ESP32-S3-5691 开发环境&#xff1a;circuitpythonthony 1 开箱 2 过程 2.1 下载固件 使用circuitpython的方式开…

MSA+抑郁症模型总结

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&#x1f3a5; 希望在…

解决Jenkins使用 Git 参数插件拉取 commit 列表缓慢问题

Jenkins使用 Git 参数插件拉取 commit 列表缓慢问题 项目问题问题描述解决方案具体实现 项目问题 在 Jenkins 中使用 Git 参数插件 进行参数化构建&#xff0c;具有多方面的重要性和好处。这不仅提高了构建的灵活性和透明度&#xff0c;还能大大提升开发和运维效率。以下是使用…

黑马智数Day7

获取行车管理计费规则列表 封装接口 export function getRuleListAPI(params) {return request({url: parking/rule/list,params}) } 获取并渲染数据 import { getRuleListAPI } from /apis/carmounted() {this.getRuleList() }methods: {// 获取规则列表async getRuleList(…

员工电脑怎么监控?这些电脑监控软件必备

在当今远程办公、灵活工时盛行的时代&#xff0c;如何掌握员工的在线活动、确保工作效率和数据安全成为许多企业关注的焦点。电脑监控软件作为管理工具中的关键一环&#xff0c;可以有效帮助企业了解员工的在线行为&#xff0c;避免效率低下和数据泄露等风险。今天我们就来介绍…

学习干货|实战学习应急响应之Windows日志分析,网络安全零基础入门到精通教程!

前言 本次环境将从大赛内与实战环境相结合去了解在应急响应中Windows日志分析的几个关键点&#xff0c;符合大赛及真实环境案例&#xff0c;本次环境将从WEB层面的日志分析到主机内的几种关键日志分析和重点功能进行排查 题目描述&#xff1a;某台Windows服务器遭到攻击者入侵…

零基础光伏人,数据计算轻松拿捏

在可再生能源领域&#xff0c;光伏产业以其清洁、可再生的特点日益受到全球关注。然而&#xff0c;对于初学者或“零基础光伏人”而言&#xff0c;光伏项目涉及的一系列数据计算和专业知识往往显得复杂而难以入手。幸运的是&#xff0c;随着技术的进步&#xff0c;一系列光伏计…

一文搞懂链表相关算法

目录 链表的逆序和截断 逆序 截断 查找链表的中间节点 力扣题 博主主页&#xff1a;东洛的克莱斯韦克-CSDN博客 链表的逆序和截断 逆序 推荐使用头插法逆序&#xff0c;首先要 new 一个虚拟头节点——newNode。如下图 链表的头节点为head&#xff0c;由cur指针指向head&a…

红外热成像技术开启光伏检测新视界

随着全球对可再生能源需求的不断增加&#xff0c;光伏发电系统的应用日益广泛。然而&#xff0c;光伏组件在长期运行中可能会出现各种故障&#xff0c;如热斑效应、隐裂、接线盒故障等&#xff0c;这些问题不仅影响光伏系统的发电效率&#xff0c;还可能引发安全隐患。 红外热成…

基于vue框架的的社区智慧养老系统1mo30(程序+源码+数据库+调试部署+开发环境)

系统程序文件列表 项目功能&#xff1a;老人,员工,老人档案,养生视频,社区医生,就医信息,在线咨询,咨询回复,菜品信息,点餐订单,服务预约,通知信息,服务评价,健康关爱,新闻公告,监控日志 开题报告内容 以下是一份基于Vue框架的社区智慧养老系统的开题报告&#xff0c;详细阐述…

龙蜥8.6 配置用户登录次数和锁定策略(已亲测)

操作系统&#xff1a;龙蜥8.6 x86_64 查看是否安装pam模块 rpm -qa | grep pam 查看可以使用的认证模块&#xff0c;因为有的系统是pam_tally2. cd /etc/pam.d ls 经过查看&#xff0c;该服务器是使用的pam_faillock 模块 打开/etc/pam.d/password-auth 的 PAM 配置文件…

【6.4】位运算-判断是否存在重复元素

一、题目 给定一个整数数组&#xff0c;判断 是否存在重复元素 。如果存在一值在数组中 出现至少两次 &#xff0c;函数返回 true 。如果数组中每个元素都不相同&#xff0c;则返回 false 。 示例 1: 输入: [ 1 , 2 , 3 , 1 ] 输出: true 示例 2: 输入: [ 1 , 2 , 3 , 4 ] 输出…

PCB打样下单流程

PCB打样下单流程 一、PCB打样在线下单流程1&#xff0e;平台登录2&#xff0e;PCB打样领券3&#xff0e;进入下单系统4&#xff0e;上传PCB文件5&#xff0e;PCB订单界面 PCB&#xff08;印刷电路板&#xff09;打样是验证设计、优化性能和推进项目进度的关键环节。随着互联网的…

Python爬虫知识体系-----正则表达式-----持续更新

数据科学、数据分析、人工智能必备知识汇总-----Python爬虫-----持续更新&#xff1a;https://blog.csdn.net/grd_java/article/details/140574349 文章目录 一、正则基础1. 为什么使用正则2. 正则与re模块简介 二、正则表达式1. 匹配单个字符与数字2. 限定符3. 定位符4. 选择匹…