文章目录

  • 简介
  • 分割数据
    • 多index
    • get_group
    • dropna
    • groups属性
    • index的层级
  • group的遍历
  • 聚合操作
    • 通用聚合方法
    • 同时使用多个聚合方法
    • NamedAgg
    • 不同的列指定不同的聚合方法
  • 转换操作
  • 过滤操作
  • Apply操作

简介

pandas中的DF数据类型可以像数据库表格一样进行groupby操作。通常来说groupby操作可以分为三部分:分割数据,应用变换和和合并数据。

本文将会详细讲解Pandas中的groupby操作。

分割数据

分割数据的目的是将DF分割成为一个个的group。为了进行groupby操作,在创建DF的时候需要指定相应的label:

df = pd.DataFrame(...:     {...:         "A": ["foo", "bar", "foo", "bar", "foo", "bar", "foo", "foo"],...:         "B": ["one", "one", "two", "three", "two", "two", "one", "three"],...:         "C": np.random.randn(8),...:         "D": np.random.randn(8),...:     }...: )...:df
Out[61]: A      B         C         D
0  foo    one -0.490565 -0.233106
1  bar    one  0.430089  1.040789
2  foo    two  0.653449 -1.155530
3  bar  three -0.610380 -0.447735
4  foo    two -0.934961  0.256358
5  bar    two -0.256263 -0.661954
6  foo    one -1.132186 -0.304330
7  foo  three  2.129757  0.445744

默认情况下,groupby的轴是x轴。可以一列group,也可以多列group:

In [8]: grouped = df.groupby("A")In [9]: grouped = df.groupby(["A", "B"])

多index

0.24版本中,如果我们有多index,可以从中选择特定的index进行group:

In [10]: df2 = df.set_index(["A", "B"])In [11]: grouped = df2.groupby(level=df2.index.names.difference(["B"]))In [12]: grouped.sum()
Out[12]: C         D
A
bar -1.591710 -1.739537
foo -0.752861 -1.402938

get_group

get_group 可以获取分组之后的数据:

In [24]: df3 = pd.DataFrame({"X": ["A", "B", "A", "B"], "Y": [1, 4, 3, 2]})In [25]: df3.groupby(["X"]).get_group("A")
Out[25]: X  Y
0  A  1
2  A  3In [26]: df3.groupby(["X"]).get_group("B")
Out[26]: X  Y
1  B  4
3  B  2

dropna

默认情况下,NaN数据会被排除在groupby之外,通过设置 dropna=False 可以允许NaN数据:

In [27]: df_list = [[1, 2, 3], [1, None, 4], [2, 1, 3], [1, 2, 2]]In [28]: df_dropna = pd.DataFrame(df_list, columns=["a", "b", "c"])In [29]: df_dropna
Out[29]: a    b  c
0  1  2.0  3
1  1  NaN  4
2  2  1.0  3
3  1  2.0  2
# Default ``dropna`` is set to True, which will exclude NaNs in keys
In [30]: df_dropna.groupby(by=["b"], dropna=True).sum()
Out[30]: a  c
b
1.0  2  3
2.0  2  5# In order to allow NaN in keys, set ``dropna`` to False
In [31]: df_dropna.groupby(by=["b"], dropna=False).sum()
Out[31]: a  c
b
1.0  2  3
2.0  2  5
NaN  1  4

groups属性

groupby对象有个groups属性,它是一个key-value字典,key是用来分类的数据,value是分类对应的值。

In [34]: grouped = df.groupby(["A", "B"])In [35]: grouped.groups
Out[35]: {('bar', 'one'): [1], ('bar', 'three'): [3], ('bar', 'two'): [5], ('foo', 'one'): [0, 6], ('foo', 'three'): [7], ('foo', 'two'): [2, 4]}In [36]: len(grouped)
Out[36]: 6

index的层级

对于多级index对象,groupby可以指定group的index层级:

In [40]: arrays = [....:     ["bar", "bar", "baz", "baz", "foo", "foo", "qux", "qux"],....:     ["one", "two", "one", "two", "one", "two", "one", "two"],....: ]....: In [41]: index = pd.MultiIndex.from_arrays(arrays, names=["first", "second"])In [42]: s = pd.Series(np.random.randn(8), index=index)In [43]: s
Out[43]:
first  second
bar    one      -0.919854two      -0.042379
baz    one       1.247642two      -0.009920
foo    one       0.290213two       0.495767
qux    one       0.362949two       1.548106
dtype: float64

group第一级:

In [44]: grouped = s.groupby(level=0)In [45]: grouped.sum()
Out[45]:
first
bar   -0.962232
baz    1.237723
foo    0.785980
qux    1.911055
dtype: float64

group第二级:

In [46]: s.groupby(level="second").sum()
Out[46]:
second
one    0.980950
two    1.991575
dtype: float64

group的遍历

得到group对象之后,我们可以通过for语句来遍历group:

In [62]: grouped = df.groupby('A')In [63]: for name, group in grouped:....:     print(name)....:     print(group)....:
barA      B         C         D
1  bar    one  0.254161  1.511763
3  bar  three  0.215897 -0.990582
5  bar    two -0.077118  1.211526
fooA      B         C         D
0  foo    one -0.575247  1.346061
2  foo    two -1.143704  1.627081
4  foo    two  1.193555 -0.441652
6  foo    one -0.408530  0.268520
7  foo  three -0.862495  0.024580

如果是多字段group,group的名字是一个元组:

In [64]: for name, group in df.groupby(['A', 'B']):....:     print(name)....:     print(group)....:
('bar', 'one')A    B         C         D
1  bar  one  0.254161  1.511763
('bar', 'three')A      B         C         D
3  bar  three  0.215897 -0.990582
('bar', 'two')A    B         C         D
5  bar  two -0.077118  1.211526
('foo', 'one')A    B         C         D
0  foo  one -0.575247  1.346061
6  foo  one -0.408530  0.268520
('foo', 'three')A      B         C        D
7  foo  three -0.862495  0.02458
('foo', 'two')A    B         C         D
2  foo  two -1.143704  1.627081
4  foo  two  1.193555 -0.441652

聚合操作

分组之后,就可以进行聚合操作:

In [67]: grouped = df.groupby("A")In [68]: grouped.aggregate(np.sum)
Out[68]: C         D
A
bar  0.392940  1.732707
foo -1.796421  2.824590In [69]: grouped = df.groupby(["A", "B"])In [70]: grouped.aggregate(np.sum)
Out[70]: C         D
A   B
bar one    0.254161  1.511763three  0.215897 -0.990582two   -0.077118  1.211526
foo one   -0.983776  1.614581three -0.862495  0.024580two    0.049851  1.185429

对于多index数据来说,默认返回值也是多index的。如果想使用新的index,可以添加 as_index = False:

In [71]: grouped = df.groupby(["A", "B"], as_index=False)In [72]: grouped.aggregate(np.sum)
Out[72]: A      B         C         D
0  bar    one  0.254161  1.511763
1  bar  three  0.215897 -0.990582
2  bar    two -0.077118  1.211526
3  foo    one -0.983776  1.614581
4  foo  three -0.862495  0.024580
5  foo    two  0.049851  1.185429In [73]: df.groupby("A", as_index=False).sum()
Out[73]: A         C         D
0  bar  0.392940  1.732707
1  foo -1.796421  2.824590

上面的效果等同于reset_index

In [74]: df.groupby(["A", "B"]).sum().reset_index()

grouped.size() 计算group的大小:

In [75]: grouped.size()
Out[75]: A      B  size
0  bar    one     1
1  bar  three     1
2  bar    two     1
3  foo    one     2
4  foo  three     1
5  foo    two     2

grouped.describe() 描述group的信息:

In [76]: grouped.describe()
Out[76]: C                                                    ...         D                                                  count      mean       std       min       25%       50%  ...       std       min       25%       50%       75%       max
0   1.0  0.254161       NaN  0.254161  0.254161  0.254161  ...       NaN  1.511763  1.511763  1.511763  1.511763  1.511763
1   1.0  0.215897       NaN  0.215897  0.215897  0.215897  ...       NaN -0.990582 -0.990582 -0.990582 -0.990582 -0.990582
2   1.0 -0.077118       NaN -0.077118 -0.077118 -0.077118  ...       NaN  1.211526  1.211526  1.211526  1.211526  1.211526
3   2.0 -0.491888  0.117887 -0.575247 -0.533567 -0.491888  ...  0.761937  0.268520  0.537905  0.807291  1.076676  1.346061
4   1.0 -0.862495       NaN -0.862495 -0.862495 -0.862495  ...       NaN  0.024580  0.024580  0.024580  0.024580  0.024580
5   2.0  0.024925  1.652692 -1.143704 -0.559389  0.024925  ...  1.462816 -0.441652  0.075531  0.592714  1.109898  1.627081[6 rows x 16 columns]

通用聚合方法

下面是通用的聚合方法:

函数 描述
mean() 平均值
sum() 求和
size() 计算size
count() group的统计
std() 标准差
var() 方差
sem() 均值的标准误
describe() 统计信息描述
first() 第一个group值
last() 最后一个group值
nth() 第n个group值
min() 最小值
max() 最大值

同时使用多个聚合方法

可以同时指定多个聚合方法:

In [81]: grouped = df.groupby("A")In [82]: grouped["C"].agg([np.sum, np.mean, np.std])
Out[82]: sum      mean       std
A
bar  0.392940  0.130980  0.181231
foo -1.796421 -0.359284  0.912265

可以重命名:

In [84]: (....:     grouped["C"]....:     .agg([np.sum, np.mean, np.std])....:     .rename(columns={"sum": "foo", "mean": "bar", "std": "baz"})....: )....:
Out[84]: foo       bar       baz
A
bar  0.392940  0.130980  0.181231
foo -1.796421 -0.359284  0.912265

NamedAgg

NamedAgg 可以对聚合进行更精准的定义,它包含 column 和aggfunc 两个定制化的字段。

In [88]: animals = pd.DataFrame(....:     {....:         "kind": ["cat", "dog", "cat", "dog"],....:         "height": [9.1, 6.0, 9.5, 34.0],....:         "weight": [7.9, 7.5, 9.9, 198.0],....:     }....: )....: In [89]: animals
Out[89]: kind  height  weight
0  cat     9.1     7.9
1  dog     6.0     7.5
2  cat     9.5     9.9
3  dog    34.0   198.0In [90]: animals.groupby("kind").agg(....:     min_height=pd.NamedAgg(column="height", aggfunc="min"),....:     max_height=pd.NamedAgg(column="height", aggfunc="max"),....:     average_weight=pd.NamedAgg(column="weight", aggfunc=np.mean),....: )....:
Out[90]: min_height  max_height  average_weight
kind
cat          9.1         9.5            8.90
dog          6.0        34.0          102.75

或者直接使用一个元组:

In [91]: animals.groupby("kind").agg(....:     min_height=("height", "min"),....:     max_height=("height", "max"),....:     average_weight=("weight", np.mean),....: )....:
Out[91]: min_height  max_height  average_weight
kind
cat          9.1         9.5            8.90
dog          6.0        34.0          102.75

不同的列指定不同的聚合方法

通过给agg方法传入一个字典,可以指定不同的列使用不同的聚合:

In [95]: grouped.agg({"C": "sum", "D": "std"})
Out[95]: C         D
A
bar  0.392940  1.366330
foo -1.796421  0.884785

转换操作

转换是将对象转换为同样大小对象的操作。在数据分析的过程中,经常需要进行数据的转换操作。

可以接lambda操作:

In [112]: ts.groupby(lambda x: x.year).transform(lambda x: x.max() - x.min())

填充na值:

In [121]: transformed = grouped.transform(lambda x: x.fillna(x.mean()))

过滤操作

filter方法可以通过lambda表达式来过滤我们不需要的数据:

In [136]: sf = pd.Series([1, 1, 2, 3, 3, 3])In [137]: sf.groupby(sf).filter(lambda x: x.sum() > 2)
Out[137]:
3    3
4    3
5    3
dtype: int64

Apply操作

有些数据可能不适合进行聚合或者转换操作,Pandas提供了一个 apply 方法,用来进行更加灵活的转换操作。

In [156]: df
Out[156]: A      B         C         D
0  foo    one -0.575247  1.346061
1  bar    one  0.254161  1.511763
2  foo    two -1.143704  1.627081
3  bar  three  0.215897 -0.990582
4  foo    two  1.193555 -0.441652
5  bar    two -0.077118  1.211526
6  foo    one -0.408530  0.268520
7  foo  three -0.862495  0.024580In [157]: grouped = df.groupby("A")# could also just call .describe()
In [158]: grouped["C"].apply(lambda x: x.describe())
Out[158]:
A
bar  count    3.000000mean     0.130980std      0.181231min     -0.07711825%      0.069390...
foo  min     -1.14370425%     -0.86249550%     -0.57524775%     -0.408530max      1.193555
Name: C, Length: 16, dtype: float64

可以外接函数:

In [159]: grouped = df.groupby('A')['C']In [160]: def f(group):.....:     return pd.DataFrame({'original': group,.....:                          'demeaned': group - group.mean()}).....: In [161]: grouped.apply(f)
Out[161]: original  demeaned
0 -0.575247 -0.215962
1  0.254161  0.123181
2 -1.143704 -0.784420
3  0.215897  0.084917
4  1.193555  1.552839
5 -0.077118 -0.208098
6 -0.408530 -0.049245
7 -0.862495 -0.503211

本文已收录于 http://www.flydean.com/11-python-pandas-groupby/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

Pandas高级教程之:GroupBy用法相关推荐

  1. Pandas高级教程之:category数据类型

    文章目录 简介 创建category 使用Series创建 使用DF创建 创建控制 转换为原始类型 categories的操作 获取category的属性 重命名categories 使用**add_ ...

  2. Pandas高级教程之:统计方法

    文章目录 简介 变动百分百 Covariance协方差 Correlation相关系数 rank等级 简介 数据分析中经常会用到很多统计类的方法,本文将会介绍Pandas中使用到的统计方法. 变动百分 ...

  3. Pandas高级教程之:plot画图详解

    文章目录 简介 基础画图 其他图像 bar stacked bar barh Histograms box Area Scatter Hexagonal bin Pie 在画图中处理NaN数据 其他作 ...

  4. Pandas高级教程之:处理缺失数据

    文章目录 简介 NaN的例子 整数类型的缺失值 Datetimes 类型的缺失值 None 和 np.nan 的转换 缺失值的计算 使用fillna填充NaN数据 使用dropna删除包含NA的数据 ...

  5. Pandas高级教程之:处理text数据

    文章目录 简介 创建text的DF String 的方法 columns的String操作 分割和替换String String的连接 使用 .str来index extract extractall ...

  6. Pandas高级教程之:自定义选项

    文章目录 简介 常用选项 get/set 选项 经常使用的选项 最大展示行数 超出数据展示 最大列的宽度 显示精度 零转换的门槛 列头的对齐方向 简介 pandas有一个option系统可以控制pan ...

  7. iText7高级教程之html2pdf——7.关于pdfHTML经常问的问题

      本章是一些问题的总结,iText官网罗列了常见的一些问题,让我们能更加了解pdfTML.一下是原文和链接,在这会一一翻译: Over the years, we've received many ...

  8. iText7高级教程之html2pdf——6.在pdfHTML中使用字体

    作者:CuteXiaoKe 微信公众号:CuteXiaoKe   到目前为止,我们还没有花太多的精力来研究将HTML转换为PDF时使用的字体.我们知道Helvetica是iText在没有指定字体时使用 ...

  9. iText7高级教程之html2pdf——1.从Hello HTML开始

    作者:CuteXiaoKe 微信公众号:CuteXiaoKe   在本章,我们通过不同的方法把一个简单的HTML文件转换为PDF文件.HTML文件的内容包含一个"TEST"标题,一 ...

最新文章

  1. python函数def里面嵌套def,python菜鸟求问关于嵌套函数中作用域范围应该怎么理解?,python嵌套,直接上代码def l(l...
  2. Fortinet宣布收购AccelOps
  3. 我以前用过的一个洗牌算法
  4. bash3与bash4数组结构
  5. Mybatis源码之与Spring集成包
  6. 常见错误:未能加载文件或程序集
  7. 数据和云,半年文章精选(文末赠书)
  8. Thinkphp开发时关闭缓存的方法
  9. VMware虚拟机中ubuntu的磁盘怎么扩容
  10. 【数据分享】全国POI数据分享(持续更新中)
  11. 亲测可用——PostgresSQL安装教程
  12. 专业卸载工具Your Uninstaller! Pro
  13. 深度学习与计算机视觉教程(6) | 神经网络训练技巧 (上)(CV通关指南·完结)
  14. Warbler, A Little Birdie To Introduce Your Rails App To Java
  15. css app菜单,简单的Material Design风格手机App菜单特效
  16. 张艺谋说高仓健:一位古代君子
  17. springboot中怎么进行统一日志处理?
  18. 【Java】广州三本秋招之路
  19. android 绘画笔迹回放_Android画板 半透明画笔 笔迹叠加效果
  20. APP稀有资源及19种无需编程的App创建工具

热门文章

  1. ctab法提取dna流程图_【分子】DNA的提取与检测(下)——质粒DNA
  2. Python配置-virtualenv和conda的区别
  3. EOJ_1057_排名汇总
  4. linux 键盘 数值,键盘数值对照表
  5. 数据库服务器(SQL SERVER)的安全设置
  6. VC程序初始化隐藏窗体
  7. Linux中的文件搜索 locate,find,grep ,whereis和which命令的使用
  8. maven打包的各种方式和如何在使用maven-assembly-plugin打包时去掉assembly id
  9. IP地址分类及CIDR划分方法
  10. 设计模式--装饰模式