专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

深入理解Pandas的groupby函数

  序
  最近在学习Pandas,在处理数据时,经常需要对数据的某些字段进行分组分析,这就需要用到groupby函数,这篇文章做一个详细记录
  Pandas版本1。4。3
  Pandas中的groupby函数先将DataFrame或Series按照关注字段进行拆分,将相同属性划分为一组,然后可以对拆分后的各组执行相应的转换操作,最后返回汇总转换后的各组结果一、基本用法
  先初始化一些数据,方便演示importpandasaspddfpd。DataFrame({name:〔香蕉,菠菜,糯米,糙米,丝瓜,冬瓜,柑橘,苹果,橄榄油〕,category:〔水果,蔬菜,米面,米面,蔬菜,蔬菜,水果,水果,粮油〕,price:〔3。5,6,2。8,9,3,2。5,3。2,8,18〕,count:〔2,1,3,6,4,8,5,3,2〕})
  按category分组groupeddf。groupby(category)print(type(grouped))print(grouped)
  输出结果classpandas。core。groupby。generic。DataFrameGroupBypandas。core。groupby。generic。DataFrameGroupByobjectat0x127112df0
  grouped的类型是DataFrameGroupBy,直接尝试输出,打印是内存地址,不太直观,这里写一个函数来展示(可以这么写的原理,后面会介绍)defviewgroup(thepdgroup):forname,groupinthepdgroup:print(fgroupname:{name})print(30)print(group)print(30,)viewgroup(grouped)
  输出结果groupname:水果namecategorypricecount0香蕉水果3。526柑橘水果3。257苹果水果8。03groupname:米面namecategorypricecount2糯米米面2。833糙米米面9。06groupname:粮油namecategorypricecount8橄榄油粮油18。02groupname:蔬菜namecategorypricecount1菠菜蔬菜6。014丝瓜蔬菜3。045冬瓜蔬菜2。58二、参数源码探析
  接下来看一下源码中的方法定义DataFrame的groupbydefgroupby(self,byNone,axis:Axis0,level:LevelNoneNone,asindex:boolTrue,sort:boolTrue,groupkeys:boolTrue,squeeze:boollib。NoDefaultnodefault,observed:boolFalse,dropna:boolTrue,)DataFrameGroupBy:pass
  Series的groupbydefgroupby(self,byNone,axis0,levelNone,asindex:boolTrue,sort:boolTrue,groupkeys:boolTrue,squeeze:boollib。NoDefaultnodefault,observed:boolFalse,dropna:boolTrue,)SeriesGroupBy:pass
  Series的groupby函数操作与DataFrame类似,这篇文章只以DataFrame作为示例入参by
  再来回忆一下基本用法里的写法groupeddf。groupby(category)
  这里传入的category就是第1个参数by,表示要按照什么进行分组,根据官方文档介绍,by可以是mapping,function,label,listoflabels中的一种,这里是用的label,也就是说,还可以像下面这样写label列表groupeddf。groupby(〔category〕)mapping
  这种方式需要按DataFrame的index进行映射,这里把水果和蔬菜划分到大组蔬菜水果,米面和粮油划分到大组米面粮油categorydict{水果:蔬菜水果,蔬菜:蔬菜水果,米面:米面粮油,粮油:米面粮油}themap{}foriinrange(len(df。index)):themap〔i〕categorydict〔df。iloc〔i〕〔category〕〕groupeddf。groupby(themap)viewgroup(grouped)
  输出结果如下groupname:米面粮油namecategorypricecount2糯米米面2。833糙米米面9。068橄榄油粮油18。02groupname:蔬菜水果namecategorypricecount0香蕉水果3。521菠菜蔬菜6。014丝瓜蔬菜3。045冬瓜蔬菜2。586柑橘水果3。257苹果水果8。03function
  这种方式下,自定义函数的入参也是DataFrame的index,输出结果与mapping的例子相同categorydict{水果:蔬菜水果,蔬菜:蔬菜水果,米面:米面粮油,粮油:米面粮油}deftobigcategory(theidx):returncategorydict〔df。iloc〔theidx〕〔category〕〕groupeddf。groupby(tobigcategory)viewgroup(grouped)axis
  axis表示以哪个轴作为分组的切分依据
  0等价于index,表示按行切分,默认
  1等价于columns,表示按列切分
  这里看一下按列切分的示例defgroupcolumns(columnname:str):ifcolumnnamein〔name,category〕:returnGroup1else:returnGroup2等价写法groupeddf。head(3)。groupby(groupcolumns,axiscolumns)groupeddf。head(3)。groupby(groupcolumns,axis1)viewgroup(grouped)
  输出结果如下groupname:Group1namecategory0香蕉水果1菠菜蔬菜2糯米米面groupname:Group2pricecount03。5216。0122。83
  相当于把表从垂直方向上切开,左半部分为Group1,右半部分为Group2level
  当axis是MultiIndex(层级结构)时,按特定的level进行分组,注意这里的level是int类型,从0开始,0表示第1层,以此类推
  构造另一组带MultiIndex的测试数据thearrays〔〔A,A,A,B,A,A,A,B,A,A〕,〔蔬菜水果,蔬菜水果,米面粮油,休闲食品,米面粮油,蔬菜水果,蔬菜水果,休闲食品,蔬菜水果,米面粮油〕,〔水果,蔬菜,米面,糖果,米面,蔬菜,蔬菜,饼干,水果,粮油〕〕theindexpd。MultiIndex。fromarrays(arraysthearrays,names〔one,two,three〕)df2pd。DataFrame(data〔3。5,6,2。8,4,9,3,2。5,3。2,8,18〕,indextheindex,columns〔price〕)print(df2)
  输出结果如下priceonetwothreeA蔬菜水果水果3。5蔬菜6。0米面粮油米面2。8B休闲食品糖果4。0A米面粮油米面9。0蔬菜水果蔬菜3。0蔬菜2。5B休闲食品饼干3。2A蔬菜水果水果8。0米面粮油粮油18。0
  1。按第3层分组groupeddf2。groupby(level2)viewgroup(grouped)
  输出结果如下groupname:水果priceonetwothreeA蔬菜水果水果3。5水果8。0groupname:米面priceonetwothreeA米面粮油米面2。8米面9。0groupname:粮油priceonetwothreeA米面粮油粮油18。0groupname:糖果priceonetwothreeB休闲食品糖果4。0groupname:蔬菜priceonetwothreeA蔬菜水果蔬菜6。0蔬菜3。0蔬菜2。5groupname:饼干priceonetwothreeB休闲食品饼干3。2
  共6个分组
  2。按第1,2层分组groupeddf2。groupby(level〔0,1〕)viewgroup(grouped)
  输出结果如下groupname:(A,米面粮油)priceonetwothreeA米面粮油米面2。8米面9。0粮油18。0groupname:(A,蔬菜水果)priceonetwothreeA蔬菜水果水果3。5蔬菜6。0蔬菜3。0蔬菜2。5水果8。0groupname:(B,休闲食品)priceonetwothreeB休闲食品糖果4。0饼干3。2
  共3个分组,可以看到,分组名称变成了元组asindex
  bool类型,默认值为True。对于聚合输出,返回对象以分组名作为索引groupedself。df。groupby(category,asindexTrue)print(grouped。sum())
  asindex为True的输出结果如下pricecountcategory水果14。710米面11。89粮油18。02蔬菜11。513groupedself。df。groupby(category,asindexFalse)print(grouped。sum())
  asindex为False的输出结果如下,与SQL的groupby输出风格相似categorypricecount0水果14。7101米面11。892粮油18。023蔬菜11。513sort
  bool类型,默认为True。是否对分组名进行排序,关闭自动排序可以提高性能。注意:对分组名排序并不影响分组内的顺序groupkeys
  bool类型,默认为True
  如果为True,调用apply时,将分组的keys添加到索引中squeeze
  1。1。0版本已废弃,不解释observed
  bool类型,默认值为False
  仅适用于任何groupers是分类(Categoricals)的
  如果为True,仅显示分类分组的观察值;如果为False,显示分类分组的所有值dropna
  bool类型,默认值为True,1。1。0版本新增参数
  如果为True,且分组的keys中包含NA值,则NA值连同行(axis0)列(axis1)将被删除
  如果为False,NA值也被视为分组的keys,不做处理返回值
  DateFrame的gropuby函数,返回类型是DataFrameGroupBy,而Series的groupby函数,返回类型是SeriesGroupBy
  查看源码后发现他们都继承了BaseGroupBy,继承关系如图所示
  BaseGroupBy类中有一个grouper属性,是ops。BaseGrouper类型,但BaseGroupBy类没有init方法,因此进入GroupBy类,该类重写了父类的grouper属性,在init方法中调用了grouper。py的getgrouper,下面是抽取出来的伪代码
  groupby。py文件classGroupBy(BaseGroupBy〔NDFrameT〕):grouper:ops。BaseGrouperdefinit(self,。。。):。。。ifgrouperisNone:frompandas。core。groupby。grouperimportgetgroupergrouper,exclusions,objgetgrouper(。。。)
  grouper。py文件defgetgrouper(。。。)tuple〔ops。BaseGrouper,frozenset〔Hashable〕,NDFrameT〕:。。。createtheinternalsgroupergrouperops。BaseGrouper(groupaxis,groupings,sortsort,mutatedmutated,dropnadropna)returngrouper,frozenset(exclusions),objclassGrouping:obj:DataFrameorSeriesdefinit(self,index:Index,grouperNone,obj:NDFrameNoneNone,levelNone,sort:boolTrue,observed:boolFalse,inaxis:boolFalse,dropna:boolTrue,):pass
  ops。py文件classBaseGrouper:ThisisaninternalGrouperclass,whichactuallyholdsthegeneratedgroups。。。。。。definit(self,axis:Index,groupings:Sequence〔grouper。Grouping〕,。。。):。。。self。groupings:list〔grouper。Grouping〕list(groupings)propertydefgroupings(self)list〔grouper。Grouping〕:returnself。groupings
  BaseGrouper中包含了最终生成的分组信息,是一个list,其中的元素类型为grouper。Grouping,每个分组对应一个Grouping,而Grouping中的obj对象为分组后的DataFrame或者Series
  在第一部分写了一个函数来展示groupby返回的对象,这里再来探究一下原理,对于可迭代对象,会实现iter()方法,先定位到BaseGroupBy的对应方法classBaseGroupBy:grouper:ops。BaseGrouperfinaldefiter(self)Iterator〔tuple〔Hashable,NDFrameT〕〕:returnself。grouper。getiterator(self。selectedobj,axisself。axis)
  接下来进入BaseGrouper类中classBaseGrouper:defgetiterator(self,data:NDFrameT,axis:int0)Iterator〔tuple〔Hashable,NDFrameT〕〕:splitterself。getsplitter(data,axisaxis)keysself。groupkeysseqforkey,groupinzip(keys,splitter):yieldkey,group。finalize(data,methodgroupby)
  Debug模式进入group。finalize()方法,发现返回的确实是DataFrame对象
  三、4大函数
  有了上面的基础,接下来再看groupby之后的处理函数,就简单多了agg
  聚合操作是groupby后最常见的操作,常用来做数据分析
  比如,要查看不同category分组的最大值,以下三种写法都可以实现,并且grouped。aggregate和grouped。agg完全等价,因为在SelectionMixin类中有这样的定义:aggaggregate
  但是要聚合多个字段时,就只能用aggregate或者agg了,比如要获取不同category分组下price最大,count最小的记录
  还可以结合numpy里的聚合函数importnumpyasnpgrouped。agg({price:np。max,count:np。min})
  常见的聚合函数如下
  聚合函数
  功能
  max
  最大值
  mean
  平均值
  median
  中位数
  min
  最小值
  sum
  求和
  std
  标准差
  var
  方差
  count
  计数
  其中,count在numpy中对应的调用方式为np。sizetransform
  现在需要新增一列pricemean,展示每个分组的平均价格
  transform函数刚好可以实现这个功能,在指定分组上产生一个与原df相同索引的DataFrame,返回与原对象有相同索引且已填充了转换后的值的DataFrame,然后可以把转换结果新增到原来的DataFrame上
  示例代码如下groupeddf。groupby(category,sortFalse)df〔pricemean〕grouped〔price〕。transform(mean)print(df)
  输出结果如下
  apply
  现在需要获取各个分组下价格最高的数据,调用apply可以实现这个功能,apply可以传入任意自定义的函数,实现复杂的数据操作frompandasimportDataFramegroupeddf。groupby(category,asindexFalse,sortFalse)defgetmaxone(thedf:DataFrame):sortdfthedf。sortvalues(byprice,ascendingTrue)returnsortdf。iloc〔1,:〕maxpricedfgrouped。apply(getmaxone)maxpricedf
  输出结果如下
  filter
  filter函数可以对分组后数据做进一步筛选,该函数在每一个分组内,根据筛选函数排除不满足条件的数据并返回一个新的DataFrame
  假设现在要把平均价格低于4的分组排除掉,根据transform小节的数据,会把蔬菜分类过滤掉groupeddf。groupby(category,asindexFalse,sortFalse)filteredgrouped。filter(lambdasubdf:subdf〔price〕。mean()4)print(filtered)
  输出结果如下
  四、总结
  groupby的过程就是将原有的DataFrameSeries按照groupby的字段,划分为若干个分组DataFrameSeries,分成多少个组就有多少个分组DataFrameSeries。因此,在groupby之后的一系列操作(如agg、apply等),均是基于子DataFrameSeries的操作。理解了这点,就理解了Pandas中groupby操作的主要原理五、参考文档
  Pandas官网关于pandas。DateFrame。groupby的介绍
  Pandas官网关于pandas。Series。groupby的介绍

重磅亮相!中国宋庄艺术市集今起试营业有展有集,还有美食街亲子乐园北青社区报(微信号tongzhoushequbao)记者了解到今日(2月21日)起,副中心再添一处网红艺术打卡地中国宋庄艺术市集一期重磅亮相,迎来试营业,包括市集大道原色音画广场好贵州十大奇葩美食,本地人吃的嘎嘎香,外地人不敢尝试文原点科普编辑原点科普说起贵州,你会想到什么?如果只有茅台,说明你还是个初级吃货,今天咱们就盘点一下,贵州十大奇葩美食,假如给你100万,你敢吃吗?第十位烤脑花你敢相信吗?看着恶心中国最好吃的十碗面,舌尖上的美食,每一口都让人念念不忘!中国是最早发展出面条技艺的国家,年代大概比公元前200年还更早。据悉,早在3000多年前的殷周时代,一些简单的面食文化便已经开始了。秦汉统一,让各地的饮食有了融合的机会,再加上生产春天的野菜别错过,鲜嫩可口又营养,这吃法既能当菜又能管饱头条创作挑战赛春天的野菜别错过,鲜嫩可口又营养,这吃法既能当菜又能管饱。春天的荠菜最受人追捧,味道鲜嫩营养好,俗称野菜,每年的春天老妈只要有空就会出去挑野菜,回来做成各种好吃的。荠破解谣传!腌制美食真的都会致癌吗?欠发达的岁月中,吃饱是人们目标。而现在,随着社会的发展,人们生活理念的革新,吃饱早已不再是人们考虑的重点。如何做到营养均衡,健康可口才是人们最在意的事。于是乎,各种有关食品安全的科7天盈利3700亿!憋惨的中国游客,到底盘活了多少景区?不得不说,疫情对老百姓产生的影响是很大的,不仅工资收入受到了影响,就连日常出行都受到了影响,去哪里都得做核酸或者是隔离,诸多不便。久而久之,大家就不愿意出门旅游了。从去年年底开始,茶产业大利好!湖南千亿茶产业链关键技术创新与示范项目启动湖南千亿茶产业链关键技术创新与示范项目启动推进会现场。红网时刻新闻2月22日讯(记者刘志雄通讯员谭浩)日前,省科技厅启动实施省产业创新链重大项目湖南千亿茶产业链关键技术创新与示范,咖啡氛围渐浓年轻人把咖啡社交带进三四线城市年轻人把咖啡社交带进三四线城市一周用了100磅豆子30箱牛乳,出杯超过2000杯。从春节开始,浙江省湖州市德清县新市古镇的企鹅咖啡一直处于爆满状态,主理人徐超每天都要从早10点一直礼部是唐代官学最高管理机构,谁负责地方管理呢?都学习什么?历史开讲周予同先生曾这样评价唐代的学校制度唐代学校制度,较诸中古的任何一代,复杂而完备。唐代的学校在具体的管理上较前代有着更为详尽的制度。唐代官学的最高管理机构礼部唐代地方官学的最日本投降后,将10万女性抛弃在东北,后来咋样了?日本至今不敢提日本人的好战是由来已久的,因为日本是一个由数千个岛屿组成的小国,国土资源自然资源非常的有限,因而对外扩张是他们快速强大的途径。自我们古代唐朝时期,日本就已经对我们边境进行侵犯,但遭品读资治通鉴你行并不是真的你行,而是你代表的势力让你行可略过原文,直接读解析和启发第87卷孝怀皇帝中永嘉三年(己巳,公元三零九年)本章主题这个案例带给我们当今职场的借鉴就是当你做到一个位置的时候,并不代表自己能力有多强,个人魅力有多高
福建舰之后下艘航母会在哪建?中国7大造船厂各有绝活03型航母下水!经中央军委批准,我国第三艘航母命名为中国人民解放军海军福建舰,舷号18。这是中国海军发展史上的一个重要时刻,标志着中国海军在现代海军最重要的战舰航母的发展上已经赶上河南晒成可南了?吊扇被烤化,拖鞋晒成童鞋,小狗追着车影躲太阳近日,河南高温凶猛,成为全国热力中心,河南高温频频占据各大热搜榜单,一度成为不少网友讨论的热点话题。河南到底有多热?对此,网友们给出了不同的答案,一起往下看。河南商丘铁皮棚内吊扇被32岁王冰冰穿校服扮学生!扎马尾戴眼镜超清纯,皮肤白皙身形消瘦近日多地高考成绩将陆续公布,美女记者王冰冰与科普视频创作者毕导一起回忆那段青葱岁月,为高考生献上暖心祝福。视频中王冰冰重返18岁,高马尾配经典蓝白校服,清纯可人。如今成熟的王冰冰也黑山峡高坝作用远小于小坡小沟小坝小流域治理,调蓄则另当别论黑山峡对甘肃来说弊大于利,因此甘肃否决了小观音高坝网友说谈黑山峡的主要利好主要有三点1建高坝自流引水到宁夏平原自流灌溉,建设西北粮仓。2建高坝发电。3建高坝大水库,通过大水面改变环唐山打人案是有预谋的,是打人主犯一次实力的展示唐山市公安局路北区分局于六月十一日下午发布了一份关于唐山一家烤肉店打人事件的通告,涉案的九名人员已全部归案。警察说,他们被控寻衅滋事,暴力殴打他人。网上有消息称,1979年出生的陈果然有问题!唐山市公安局路北分局局长等人被查正义不会缺席,人民的强大力量终于撕开了一个口子,看到了胜利的曙光。披着羊皮的狼最可怕!我整理了一下唐山打人事件以来的新闻时间轴。从6月10日到现在,各平台和新闻网站一直在持续报道和重磅!资本市场十年成绩单主要指数稳中有升,投资者超2亿,外资连续多年保持净流入股票市场规模增239点蓝字关注,不迷路资本市场过去十年的成绩单如何,证监会副主席李超给出了明确的答案。6月23日,李超在参加中宣部中国这十年系列主题新闻发布会上表示,资本市场正发生深刻的结构性变化,市娱乐圈最讨嫌女星大PK,网友听到名字就已经翻白眼了了在娱乐圈混,绝非靠着容貌就行,有的人一时能够出头,可是很快就会沉寂下去,说到底最后还是要看情商。娱乐圈里,这样的一群女星,情商低到登峰造极的程度,让人尬到翻白眼,每次看到她们都觉得他到底是喜欢男生还是女生?咱们前段时间,刚唠完尹正的前绯闻女友蒋梦婕,貌似另结新欢。结果,最近尹正就上了热搜。只不过这热搜,貌似不太正常。最近,尹正被狗仔拍到深夜和朋友聚餐。酒足饭饱,各回各家的话,这顶多也大脑喜欢的,不一定是核桃,或是这3种富含卵磷脂的食物人体的大脑是十分重要的神经器官,负责控制运动产生感觉及思维意识等重要功能。科学家曾表示,人体的大脑中约有一百四十亿个细胞,人类大脑重量平均在一千四百克左右,大脑皮层厚度约在23毫米iPhone14系列电池容量曝光,感觉iPhone14Max要火距离iPhone14系列发布只有3个月左右的时间,网上的爆料信息也越来越多了,最近就有网友曝光了iPhone14系列的电池容量,具体情况如下iPhone143279mAhiPhon
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网