不再纠结,一文详解pandas中的map、apply、applymap、groupby、agg...

pandas里applymap、apply、map、agg、groupby、自定义函数的使用 Pandas里三种调用函数应用的方法: 1:apply作用于DF的列或行 2:applymap作用于DF的所有元素 3:map作用于Series的所有元素 agg函数很多情况下都是和groupby组合使用,通常指代分组聚合,它和apply的区别不是很明显,一般当调用自定义函数,没有聚... 阅读详情

点击蓝字关注我,有干货领取!

文章的数据和代码都已上传至我的github仓库:https://github.com/CNFeffery/DataScienceStudyNotes

一、简介

pandas提供了很多方便简洁的方法,用于对单列、多列数据进行批量运算或分组聚合运算,熟悉这些方法后可极大地提升数据分析的效率,也会使得你的代码更加地优雅简洁。

本文就将针对pandas中的map()、apply()、applymap()、groupby()、agg()等方法展开详细介绍,并结合实际例子帮助大家更好地理解它们的使用技巧。

二、非聚合类方法

这里的非聚合指的是数据处理前后没有进行分组操作,数据列的长度没有发生改变,因此本章节中不涉及groupby()。

首先读入数据,这里使用到的全美婴儿姓名数据,包含了1880-2018年全美每年对应每个姓名的新生儿数据,在jupyterlab中读入数据并打印数据集的一些基本信息以了解我们的数据集:

import pandas as pd

#读入数据
data = pd.read_csv('data.csv')
data.head()
#查看各列数据类型、数据框行列数
print(data.dtypes)
print()
print(data.shape)

2.1 map()

类似Python内建的map()方法,pandas中的map()方法将函数、字典索引或是一些需要接受单个输入值的特别的对象与对应的单个列的每一个元素建立联系并串行得到结果。

譬如这里我们想要得到gender列的F、M转换为女性、男性的新列,可以有以下几种实现方式:

  • 字典映射

这里我们编写F、M与女性、男性之间一一映射的字典,再利用map()方法来得到映射列:

#定义F->女性,M->男性的映射字典
gender2xb = {'F': '女性', 'M': '男性'}
#利用map()方法得到对应gender列的映射列
data.gender.map(gender2xb)

  • lambda函数

这里我们向map()中传入lambda函数来实现所需功能:

#因为已经知道数据gender列性别中只有F和M所以编写如下lambda函数
data.gender.map(lambda x:'女性' if x is 'F' else '男性')
  • 常规函数

也可以传入def定义的常规函数:

def gender_to_xb(x):

    return '女性' if x is 'F' else '男性'

data.gender.map(gender_to_xb)

map()可以传入的内容有时候可以很特殊,如下面的例子:

  • 特殊对象

一些接收单个输入值且有输出的对象也可以用map()方法来处理:

data.gender.map("This kid's gender is {}".format)

map()还有一个参数na_action,类似R中的na.action,取值为None或ingore,用于控制遇到缺失值的处理方式,设置为ingore时串行运算过程中将忽略Nan值原样返回。

2.2 apply()

apply()堪称pandas中最好用的方法,其使用方式跟map()很像,主要传入的主要参数都是接受输入返回输出。

但相较于map()针对单列Series进行处理,一条apply()语句可以对单列或多列进行运算,覆盖非常多的使用场景。

下面我们来分别介绍:

  • 单列数据

这里我们参照2.1向apply()中传入lambda函数:

data.gender.apply(lambda x:'女性' if x is 'F' else '男性')

可以看到这里实现了跟map()一样的功能。

  • 输入多列数据

apply()最特别的地方在于其可以同时处理多列数据,我们先来了解一下如何处理多列数据输入单列数据输出的情况。

譬如这里我们编写一个使用到多列数据的函数用于拼成对于每一行描述性的话,并在apply()用lambda函数传递多个值进编写好的函数中(当调用DataFrame.apply()时,apply()在串行过程中实际处理的是每一行数据,而不是Series.apply()那样每次处理单个值)。

注意在处理多个值时要给apply()添加参数axis=1:

def generate_descriptive_statement(year, name, gender, count):
    year, count = str(year), str(count)
    gender = '女性' if gender is 'F' else '男性'
    
    return '在{}年,叫做{}性别为{}的新生儿有{}个。'.format(year, name, gender, count)

data.apply(lambda row:generate_descriptive_statement(row['year'],
                                                      row['name'],
                                                      row['gender'],
                                                      row['count']),
           axis = 1)


  • 输出多列数据

有些时候我们利用apply()会遇到希望同时输出多列数据的情况,在apply()中同时输出多列时实际上返回的是一个Series,这个Series中每个元素是与apply()中传入函数的返回值顺序对应的元组。

比如下面我们利用apply()来提取name列中的首字母和剩余部分字母:

data.apply(lambda row: (row['name'][0], row['name'][1:]), axis=1)

可以看到,这里返回的是单列结果,每个元素是返回值组成的元组,这时若想直接得到各列分开的结果,需要用到zip(*zipped)来解开元组序列,从而得到分离的多列返回值:

a, b = zip(*data.apply(lambda row: (row['name'][0], row['name'][1:]), axis=1))
print(a[:10])
print(b[:10])
  • 结合tqdm给apply()过程添加进度条

我们知道apply()在运算时实际上仍然是一行一行遍历的方式,因此在计算量很大时如果有一个进度条来监视运行进度就很舒服。

tqdm:用于添加代码进度条的第三方库

tqdm对pandas也是有着很好的支持。

我们可以使用progress_apply()代替apply(),并在运行progress_apply()之前添加tqdm.tqdm.pandas(desc='')来启动对apply过程的监视。

其中desc参数传入对进度进行说明的字符串,下面我们在上一小部分示例的基础上进行改造来添加进度条功能:

from tqdm import tqdm

def generate_descriptive_statement(year, name, gender, count):
    year, count = str(year), str(count)
    gender = '女性' if gender is 'F' else '男性'
    
    return '在{}年,叫做{}性别为{}的新生儿有{}个。'.format(year, name, gender, count)

#启动对紧跟着的apply过程的监视
tqdm.pandas(desc='apply')
data.progress_apply(lambda row:generate_descriptive_statement(row['year'],
                                                      row['name'],
                                                      row['gender'],
                                                      row['count']),
          axis = 1)

可以看到在jupyter lab中运行程序的过程中,下方出现了监视过程的进度条,这样就可以实时了解apply过程跑到什么地方了。

  • 结合tqdm_notebook()给apply()过程添加美观进度条

熟悉tqdm的朋友都知道其针对jupyter notebook开发了ui更加美观的tqdm_notebook()。

而要想在jupyter notebook/jupyter lab平台上为pandas的apply过程添加美观进度条,可以参照如下示例:

from tqdm._tqdm_notebook import tqdm_notebook

tqdm_notebook.pandas(desc='apply')
data.progress_apply(lambda row:generate_descriptive_statement(row['year'],
                                                      row['name'],
                                                      row['gender'],
                                                      row['count']),
          axis = 1)

这时所添加的进度条就美观了不少。

2.3  applymap()

applymap()是与map()方法相对应的专属于DataFrame对象的方法,类似map()方法传入函数、字典等,传入对应的输出结果。

不同的是applymap()将传入的函数等作用于整个数据框中每一个位置的元素,因此其返回结果的形状与原数据框一致。

譬如下面的简单示例,我们把婴儿姓名数据中所有的字符型数据消息小写化处理,对其他类型则原样返回:

def lower_all_string(x):
    if isinstance(x, str):
        return x.lower()
    else:
        return x

data.applymap(lower_all_string)

其形状没有变化:

配合applymap(),可以简洁地完成很多数据处理操作。

三、聚合类方法

有些时候我们需要像SQL里的聚合操作那样将原始数据按照某个或某些离散型的列进行分组再求和、平均数等聚合之后的值,在pandas中分组运算是一件非常优雅的事。

3.1 利用groupby()进行分组

要进行分组运算第一步当然就是分组,在pandas中对数据框进行分组使用到groupby()方法。

其主要使用到的参数为by,这个参数用于传入分组依据的变量名称,当变量为1个时传入名称字符串即可。

当为多个时传入这些变量名称列表,DataFrame对象通过groupby()之后返回一个生成器,需要将其列表化才能得到需要的分组后的子集,如下面的示例:

#按照年份和性别对婴儿姓名数据进行分组
groups = data.groupby(by=['year','gender'])
#查看groups类型
type(groups)

可以看到它此时是生成器,下面我们用列表解析的方式提取出所有分组后的结果:

#利用列表解析提取分组结果
groups = [group for group in groups]

查看其中的一个元素:

可以看到每一个结果都是一个二元组,元组的第一个元素是对应这个分组结果的分组组合方式,第二个元素是分组出的子集数据框,而对于DataFrame.groupby()得到的结果。

主要可以进行以下几种操作:

  • 直接调用聚合函数

譬如这里我们提取count列后直接调用max()方法:

#求每个分组中最高频次
data.groupby(by=['year','gender'])['count'].max()

注意这里的year、gender列是以索引的形式存在的,想要把它们还原回数据框,使用reset_index(drop=False)即可:


  • 结合apply()

分组后的结果也可以直接调用apply(),这样可以编写更加自由的函数来完成需求,譬如下面我们通过自编函数来求得每年每种性别出现频次最高的名字及对应频次。

要注意的是,这里的apply传入的对象是每个分组之后的子数据框,所以下面的自编函数中直接接收的df参数即为每个分组的子数据框:

import numpy as np

def find_most_name(df):
    return str(np.max(df['count']))+'-'+df['name'][np.argmax(df['count'])]

data.groupby(['year','gender']).apply(find_most_name).reset_index(drop=False)


3.2 利用agg()进行更灵活的聚合

agg即aggregate,聚合,在pandas中可以利用agg()对Series、DataFrame以及groupby()后的结果进行聚合。

其传入的参数为字典,键为变量名,值为对应的聚合函数字符串,譬如{'v1':['sum','mean'], 'v2':['median','max','min]}就代表对数据框中的v1列进行求和、均值操作,对v2列进行中位数、最大值、最小值操作。

下面用几个简单的例子演示其具体使用方式:

  • 聚合Series

在对Series进行聚合时,因为只有1列,所以可以不使用字典的形式传递参数,直接传入函数名列表即可:

#求count列的最小值、最大值以及中位数
data['count'].agg(['min','max','median'])
  • 聚合数据框

对数据框进行聚合时因为有多列,所以要使用字典的方式传入聚合方案:

 data.agg({'year': ['max','min'], 'count': ['mean','std']})

值得注意的是,因为上例中对于不同变量的聚合方案不统一,所以会出现NaN的情况。

  • 聚合groupby()结果

data.groupby(['year','gender']).agg({'count':['min','max','median']}).reset_index(drop=False)

可以注意到虽然我们使用reset_index()将索引列还原回变量,但聚合结果的列名变成红色框中奇怪的样子,而在pandas 0.25.0以及之后的版本中,可以使用pd.NamedAgg()来为聚合后的每一列赋予新的名字:

data.groupby(['year','gender']).agg(
    min_count=pd.NamedAgg(column='count', aggfunc='min'),
    max_count=pd.NamedAgg(column='count', aggfunc='max'),
    median=pd.NamedAgg(column='count', aggfunc='median')).reset_index(drop=False)

以上就是本文全部内容,如有笔误望指出!

-END-

TIPS

加入Python知识星球有丰富数据分析案例哦!

往期精选

Python3十大经典错误及解决办法

Python大数据分析

data creats value

长按二维码关注

pandas指定单元格背景颜色_利用pandas进行数据处理和操作 import os, sys import pandas as pd import numpy as np PATH = os.getcwd() + '/' # 数据可视化notebook里下载好了文件 os.chdir(PATH) df = pd.read_csv(PATH + 'iris.data', names=['sepal length', 'sepal width', 'petal ... 阅读详情

相关推荐

stata:stata软件教程(人大十八讲)(1) 第一章 stata入门

第一章 stata入门1.1 安装1.2 启用和退出1.3 打开和查看数据1.4 寻求帮助与网络资源1.5 命令示例1.6 几个环境设置1.7 复习与练习1.8 附录 注:教材为:Stata 统计分析教程 stata软件教程(人大十八讲) 中国人民大学出版社 陈传波 1.1 安装 1.2 启用和退出 1.3 打开和查看数据 1.4 寻求帮助与网络资源 1.5 命令示例 1.6 几个环境设置 1.7 复习与练习 1.8 附录 ...

qq_47805483的博客 1万+

讲解python中groupby()的应用及groupby案例分析

讲解python中groupby()的应用

weixin_46713695的博客 1万+

uni-app一键登录实战:从云函数配置到前端调用的完整指南

本文详细介绍了uni-app中一键登录功能的实现方法,从DCloud控制台配置到云函数开发,再到前端调用全流程。通过一键登录,用户无需输入账号密码即可快速使用本机手机号登录,显著提升用户体验和登录转化率。文章还提供了常见问题排查和安全合规要点,帮助开发者高效完成集成。

weixin_29291573的博客 445

pandas学习总结系列(五)

关于计算 分组 类似于sql里面的分组查询。result = df.groupby('A') 得到的result是个对象。可以使用count,max,min等得出所需的值。a = df.groupby('X').min() 如果需要得到某一项分组的很多指标。可以使用print(result['Y'].agg([np.sum,np.mean])) Y列里面没一组的和和平均数 也可以使用匿名函数grouped['C'].agg([lambda x: x.max() - x.min(),

eri_c的博客 454

IGV新手必看:5分钟搞定ChIP-seq/DAP-seq/ATAC-seq数据可视化(附常见报错解决方案)

本文为IGV新手提供了一份快速上手的实战指南,详细讲解了如何高效完成ChIP-seq、DAP-seq、ATAC-seq等数据的可视化。内容涵盖软件安装、基因组导入、文件格式转换与优化,并重点剖析了“导入后一片空白”等常见报错的根本原因与解决方案,帮助用户在5分钟内避开雷区,生成可用于发表的IGV专业图谱。

weixin_29198045的博客 539

量子城域网系列(六):从星型到环形,解析QKD网络拓扑的演进与选型

本文深入解析了量子密钥分发网络从星型到环形等主流拓扑结构的演进历程与核心原理。针对量子城域网的实际部署,文章详细对比了星型、总线型和环形拓扑的优缺点,并结合政务云、金融网点等典型应用场景,提供了实战选型指南,帮助读者在物理限制、安全需求与成本效率间找到最佳平衡。

weixin_29197835的博客 111

pandas中 map,apply的用法和进度条设置

在pandas中一般有两种数据结构对象Series、DataFrame。想要批量精心化操作Series、DataFrame就需要使用配套方法:map、apply和applymap构造实验数据集 参数: arg : function, dict, or Series na_action : 取值为 {None, ‘ignore’}, 默认为 None 返回值: Pandas Series with same as index as caller 1、把数据集中gender列的男替换为1,女替换为0,怎么做呢?

m0_43609475的博客 4595

【全网最新】使用 1panel面板 部署若依系统( springboot 和 vue)项目

打开前端项目的vue.config.js文件,检查devServer下的proxy代理部分,然后将下面这个端口修改为你要在打包后访问的端口,即使用nginx代理前的接口。这个端口默认是80端口,这里把其修改为不会冲突的8010端口,后台接口的地址配置为9080,不过感觉这里设置的8010和9080可能没有用,因为部署前端静态页面是,也配置了一次网页的外部接口和api的接口,后期有空了再验证。打开右侧的Maven,点击:生存期->package,然后点击运行,等待打包成功,包在如图所示的文件夹中。

老薛的专栏 1756

tqdm搭配pandas的progress_apply显示进度条

pandas python tqdm

niubiqigai的博客 4550

【深度学习基础】多任务学习(Multi-Task Learning)

多任务学习(Multi-task learning)是和单任务学习(single-task learning)相对的一种机器学习方法。在机器学习领域,标准的算法理论是一次学习一个任务,也就是系统的输出为实数的情况。复杂的学习问题先被分解成理论上独立的子问题,然后分别对每个子问题进行学习,最后通过对子问题学习结果的组合建立复杂问题的数学模型。多任务学习是一种联合学习,多个任务并行学习,结果相互影响。一次只学习一个任务(task),大部分的机器学习任务都属于单任务学习。

十二月的猫 1万+

线性自抗扰控制(LADRC)系统算法框图

NLADRC自抗扰控制从Simulink仿真到PLC控制实现_自抗扰控制器 simulink仿真-优快云博客本文介绍了如何将ADRC自抗扰控制算法从Simulink仿真应用到PLC控制中,包括Simulink框图、TD微分器模型、MATLAB函数的使用、SCL控制代码,以及非线性状态误差反馈控制率的实现。提供了详细的MATLAB仿真步骤和PLC源代码链接。ADRC自抗扰控制算法(含梯形图完整源代码和算法公式)_adrc算法-优快云博客。

RXXW_Dor的博客 1463

pandas 小技巧——如何显示程序进度/进度条的使用/tqdm的使用

python的进度条库:tqdm

lanyuelvyun的博客 2787

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

详解pandas中的map()、apply()、applymap()、groupby()、agg()

以下文章来源于Python大数据分析 ,作者费弗里 一、简介 pandas提供了很多方便简洁的方法,用于对单列、多列数据进行批量运算或分组聚合运算,熟悉这些方法后可极大地提升数据分析的效率,也会使得你的代码更加地优雅简洁。 本文就将针对pandas中的map()、apply()、applymap()、groupby()、agg()等方法展开详细介绍,并结合实际例子帮助大家更好地理解它们的使用技巧。...

weixin_42355670的博客 2172

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Pandas数据分析——超好用的Groupby与map、apply、applymap详解

Groupby详解 在日常的数据分析中,经常需要将数据根据某个(多个)字段划分为不同的群体(group)进行分析,如电商领域将全国的总销售额根据省份进行划分,分析各省销售额的变化情况,社交领域将用户根据画像(性别、年龄)进行细分,研究用户的使用情况和偏好等。在Pandas中,上述的数据处理操作主要运用groupby完成,这篇文章就介绍一下groupby的基本原理及对应的agg、transform和apply操作。 为了后续图解的方便,采用模拟生成的10个样本数据,代码和数据如下: co...

qq_37692302的博客 5580

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

DataFrame的apply()、applymap()、map()方法

对DataFrame对象中的某些行或列,或者对DataFrame对象中的所有元素进行某种运算或操作,我们无需利用低效笨拙的循环,DataFrame给我们分别提供了相应的直接而简单的方法,apply()和applymap()。其中apply()方法是针对某些行或列进行操作的,而applymap()方法则是针对所有元素进行操作的。 1 map()方法 The map method ...

不曾走远的博客 9万+

dataframe groupby_详解pandas中的map、apply、applymap、groupby、agg.

一、简介pandas提供了很多方便简洁的方法,用于对单列、多列数据进行批量运算或分组聚合运算,熟悉这些方法后可极大地提升数据分析的效率,也会使得你的代码更加地优雅简洁。本文就将针对pandas中的map()、apply()、applymap()、groupby()、agg()等方法展开详细介绍,并结合实际例子帮助大家更好地理解它们的使用技巧。二、非聚合类方法这里的非聚合指的是数据处理前后没有进行分...

weixin_39968266的博客 581

(数据科学学习手札69)详解pandas中的map、apply、applymap、groupby、agg

*从本篇开始所有文章的数据和代码都已上传至我的github仓库:https://github.com/CNFeffery/DataScienceStudyNotes 一、简介   pandas提供了很多方便简洁的方法,用于对单列、多列数据进行批量运算或分组聚合运算,熟悉这些方法后可极大地提升数据分析的效率,也会使得你的代码更加地优雅简洁,本文就将针对pandas中的map()、app...

weixin_30823001的博客 885

apply、applymap、transform、agg在dataframe中的用法

apply apply方法可以被groupby、resampler、dataframe、series、offsets等对象调用。 dataframe的apply方法的官方文档 其用法为pandas.DataFrame.apply(self, func, axis=0, raw=False, result_type=None) 文档中关于func参数,只说了是要应用到行或列的函数。 agg可以做的,好像apply都可以做,所以apply比agg更加灵活,更一般化,但是调用Python内置函数和pandas函数

Emma_Wason的博客 1547

cartographer运行没有map_详解pandas中的map、apply、applymap、groupby、agg.

一、简介pandas提供了很多方便简洁的方法,用于对单列、多列数据进行批量运算或分组聚合运算,熟悉这些方法后可极大地提升数据分析的效率,也会使得你的代码更加地优雅简洁。本文就将针对pandas中的map()、apply()、applymap()、groupby()、agg()等方法展开详细介绍,并结合实际例子帮助大家更好地理解它们的使用技巧。二、非聚合类方法这里的非聚合指的是数据处理前后没有进行分...

weixin_35276012的博客 181

python pandas series想赋予新的值_(数据科学学习手札69)详解pandas中的map、apply、applymap、groupby、agg...

摘要:组中最高频次data.groupby(by=['year','gender'])['count'].max()  注意这里的year、gender列是以索引的形式存在的,想要把它们还原回数据框,使用reset_index(drop=False)即可:●结合apply()  分组后的结果也可以直接调用ap一、简介pandas提供了很多方便简洁的方法,用于对单列、多列数据进行批量运算或分...

weixin_39704246的博客 251

数据分析Pandas专栏---第四章<Pandas几个处理元素的函数>

apply、map、applymap、transform、agg 和 groupby,并给出了详细的案例来说明它们的用法。apply函数可以在 Series 和 DataFrame 对象上应用自定义函数,对每个元素或每一列/行进行操作。map函数用于 Series 对象,在元素级别上进行映射或替换操作,可以根据映射关系将一些值替换为其他值。applymap函数适用于 DataFrame 对象,它用于对每个元素执行指定的函数,将函数应用于整个 DataFrame。transform。

晦涩难董先生 1508

pandas apply lambda_一分钟一个Pandas小技巧(二)

“在逛Kaggle的时候发现了一篇不错的Pandas技巧,我将挑选一些有用的并外加一些自己的想法分享给大家。本系列虽基础但带仍有一些奇怪操作,粗略扫一遍,您或将发现一些您需要的技巧。”纸上得来终觉浅,绝知此事要躬行,所谓的熟练使用Pandas是建立在您大致了解每个函数功能上,希望本系列能给您带来些许收获。本篇所涉及知识点:map、apply、applymapgroupbyMultiIn...

weixin_39539807的博客 534
上一篇: 还在用Excel的vlookup?Python几行代码就能搞定!
下一篇: Python数据分析之时间处理技巧1,2,3
严小样儿
博客等级 码龄8年 183粉丝 21原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值