我是一名苦苦挣扎在编程链底端的pythoner,工作中既要和数据打交道,也要保持和erp系统,web网站友好的沟通···,会时不时的分享下工作中遇到有意思的事情,分享个人觉得值得记录的编程小技巧,还有就是遇到的问题以及解决方案,还有源码的阅读等等,不说了,我要去重构我的程序了
groupby概念
groupby语句在数据分析中是用来做分组计算的,将数据划分为不同的部分,常用的统计指标有:计数,求和,求最大最小值,平均值等等···
# 基本用法如下ret_df = df.groupby(by=["分类a", "分类b", "分类c" ])["要计算的列名", "要计算的列名"].agg({"列名":函数名, "列名":函数名})# 参数简单解释下by中的参数为列名agg中的字典为要统计字段对应的聚合函数的名称,比如: {"column1": min, "column2": sum}
agg函数基本操作: 传入字典和列表的区别
直接上案例
import pandas as pdimport numpy as npdf = pd.DataFrame({ "类型": ["淘气", "淘气", "乖巧", "乖巧", "淘气"], "文化课成绩": np.random.randint(1, 100, size=5), "体育成绩": np.random.randint(1, 100, size=5)})# df测试数据一览:类型文化课成绩体育成绩0淘气25491淘气81722乖巧88433乖巧5654淘气9053# 将数据按照类型先进行分组grouped = df.groupby(by=["类型"])
- 直接用列表的形式就是 将每一列分别聚合求平均数,和,标准差,如下所示
# 直接用列表(注意,要把函数名用双引号括起来)ret = grouped.agg(["mean", "sum", "std"])>>> 文化课成绩体育成绩meansumstdmeansumstd类型乖巧60.00000012029.69848552.00000010456.568542淘气60.66666718238.73413722.3333336715.044379
- 传入字典则是根据不同的列分别聚合不同的函数,如下所示
ret = grouped.agg([("文化课成绩", "mean"), ("体育成绩", "sum")])# ret结果文化课成绩体育成绩文化课成绩体育成绩文化课成绩体育成绩类型乖巧60.00000012052.000000104淘气60.66666718222.33333367
groupby稍微高端一点的操作: 按照自定义分类进行聚合操作
有时候,我们对于完全没有关系的列,要进行聚合操作,这时候我们可以选择如下方法进行自定义分组条件(传入字典的形式)
构造案例,如下
# 乍一看没有任何关系,但是需要你把不同的列按照要求求和,算出每个人的总数(假设是每列糖的数量)import pandas as pdimport numpy as nppeople_df = pd.DataFrame(np.random.randint(1, 20, size=(5, 5)), columns=["a", "b", "c", "d", "e"], index=["JOE", "STEVE", "WES", "JIM", "TRAVIS"])people_df.iloc[2:3, 1:3] = np.nan>>> people_df a b c d eJOE 6 12.0 18.0 6 2STEVE 10 13.0 11.0 7 3WES 17 NaN NaN 6 12JIM 11 4.0 2.0 3 6TRAVIS 18 7.0 10.0 12 19
- 如果说希望将a,b,e划分为同一种类别,c/d为同一类别,f自己为一类,求每个人实际拥有的数量,那么就可以如下图方法处理
mapping_dic = {"a": "red", "b": "red", "c": "blue", "d": "blue", "e": "red", "f": "orange"}# 构造自定义数据结构将数据集进行聚合操作by_column = people_df.groupby(mapping_dic, axis=1).sum()>>> by_column blue redJOE 24.0 20.0STEVE 18.0 26.0WES 6.0 29.0JIM 5.0 21.0TRAVIS 22.0 44.0
按照不同标准将同类数据聚合到一行
啥意思,就比如说,一个数据集合中有性别一列,现在需要将性别为男女的分开,将所有男性的某些特征汇总到一行,用逗号分隔,女性同样如此
举例如下所示
df = pd.DataFrame({'name':['小明','小红','小陈','小绿'], 'data':[1,2,3,4], 'data_type':['apple','bear','meat','sheep'], 'gender':['male','unknown','female','male']})# 现在要实现的就是将男生爱吃的水果合并到一起,女生合并到一起,用逗号分隔>>> dfnamedatadata_typegender0小明1applemale1小红2bearunknown2小陈3meatfemale3小绿4sheepmale
- 其实这种乍一看也是分组,但是涉及到不同的语法了,解决方案如下所示
# 专门指定某列如何处理,这里是将水果划分到一起,聚合new_df = df.groupby(['gender']).agg({'data_type': [', '.join]}).reset_index()>>> new_dfgenderdata_type0femalemeat1maleapple, sheep2unknownbear
将分组后的数据列保持原列名
其实这个说简单也简单,不过当时我不知道这个方法的时候,走了很多的弯路,所以还是拿出来分享下
- as_index=False 这个参数的作用,是不将聚合后的名称更改为索引,我个人觉得很有用,尤其是需要进行数据集拼接聚合之后,可能还要关联表
# 还是用上个例子,这里就不重新构造案例数据了new_df = df.groupby(['gender'], as_index=False).sum()# 聚合之后,列名还在原位置>>> genderdata0female31male52unknown2# 如果不加这个参数呢,我们来看下new_df = df.groupby(['gender']).sum()# 看到了吧,不加列名,就成索引了datagenderfemale3male5unknown2