Pandas分组聚合基础

Pandas分组聚合 - 基础


数据分析阶段:

数据规整(清洗)阶段后,下一阶段就是 分组聚合

对数据集分组并对各组应用一个函数是数据分析中的重要环节
一般将数据准备好后,首先就是计算分组统计
sql能够方便的连接、过滤、转换和聚合数据,但sql能执行的分组运算种类有限,Pandas则强大灵活的多

In [1]:

import numpy as np
import pandas as pd

某班若干为同学的 三次、语文、数学、英语 考试成绩

In [2]:

df = pd.DataFrame({
    'name': ['张三','李四','王五','李四','王五','王五','赵六'],
    'chinese': [18, 53, 67, 63, 39, 70, 94],
    'math': [82, 63, 41, 59, 46, 39, 58],
    'english': [68, 52, 90, 86, 60, 98, 64],
    'test': ['一','一','一','二','二','三','一']
})

df

Out[2]:

name chinese math english test
0 张三 18 82 68
1 李四 53 63 52
2 王五 67 41 90
3 李四 63 59 86
4 王五 39 46 60
5 王五 70 39 98
6 赵六 94 58 64

In [3]:

df.index

Out[3]:

RangeIndex(start=0, stop=7, step=1)

In [4]:

df.columns

Out[4]:

Index(['name', 'chinese', 'math', 'english', 'test'], dtype='object')

数据聚合

一般指应用某些方法(自定义的聚合函数或系统自带Pandas的统计方法等)给数据降维

In [5]:

df

Out[5]:

name chinese math english test
0 张三 18 82 68
1 李四 53 63 52
2 王五 67 41 90
3 李四 63 59 86
4 王五 39 46 60
5 王五 70 39 98
6 赵六 94 58 64

In [6]:

df.mean()  # 平均值

Out[6]:

chinese    57.714286
math       55.428571
english    74.000000
dtype: float64

In [7]:

type(df.mean())

Out[7]:

pandas.core.series.Series

In [8]:

df.sum()  # 求和,聚合,降维

Out[8]:

name       张三李四王五李四王五王五赵六
chinese               404
math                  388
english               518
test              一一一二二三一
dtype: object

In [9]:

df.sum(axis=1)

Out[9]:

0    168
1    168
2    198
3    208
4    145
5    207
6    216
dtype: int64

In [13]:

18 + 82 + 68

Out[13]:

168

In [14]:

df.count()
df.count(axis=1)

# 计数最常用的方法是.size()

Out[14]:

0    5
1    5
2    5
3    5
4    5
5    5
6    5
dtype: int64

In [15]:

df.describe()  # describe,也可以用在这里,但它并非聚合运算(但经常当成聚合运算使用)

Out[15]:

chinese math english
count 7.000000 7.000000 7.000000
mean 57.714286 55.428571 74.000000
std 24.260491 14.998413 17.281975
min 18.000000 39.000000 52.000000
25% 46.000000 43.500000 62.000000
50% 63.000000 58.000000 68.000000
75% 68.500000 61.000000 88.000000
max 94.000000 82.000000 98.000000

数据分组

分组聚合:groupby(),一般指以下一个或多个操作步骤的集合

Splitting 分组
Applying 每个分组应用函数
Combining 合并

image.png

In [16]:


df

Out[16]:

name chinese math english test
0 张三 18 82 68
1 李四 53 63 52
2 王五 67 41 90
3 李四 63 59 86
4 王五 39 46 60
5 王五 70 39 98
6 赵六 94 58 64

In [18]:

# 一般统计指标,聚合运算不能体现表格的进一步的信息
df.mean()

Out[18]:

chinese    57.714286
math       55.428571
english    74.000000
dtype: float64

In [19]:

# 分组
df.groupby('name')

Out[19]:


基础,重要

In [20]:

df

Out[20]:

name chinese math english test
0 张三 18 82 68
1 李四 53 63 52
2 王五 67 41 90
3 李四 63 59 86
4 王五 39 46 60
5 王五 70 39 98
6 赵六 94 58 64

最常用的聚合函数:

  • 平均值:.mean() (透视表)
  • 个数:.size() (交叉表)

求每位同学、每科成绩的平均分

In [25]:

# 先分组,再聚合
x = df.groupby('name').mean()  # 平均值
x

Out[25]:

chinese math english
name
张三 18.000000 82.0 68.000000
李四 58.000000 61.0 69.000000
王五 58.666667 42.0 82.666667
赵六 94.000000 58.0 64.000000

In [22]:

# 王五的语文成绩
(67+39+70)/3

Out[22]:

58.666666666666664

In [26]:

type(x)

Out[26]:

pandas.core.frame.DataFrame

In [28]:

x.loc[['张三', '王五'], 'chinese']

Out[28]:

name
张三    18.000000
王五    58.666667
Name: chinese, dtype: float64

求每位同学的考试次数

In [23]:

df.groupby('name').size()  # 分组数据出现的行数

Out[23]:

name
张三    1
李四    2
王五    3
赵六    1
dtype: int64

In [29]:

# 分组数据在每一列出现的行数,因为重复所以不常用
df.groupby('name').count()

Out[29]:

chinese math english test
name
张三 1 1 1 1
李四 2 2 2 2
王五 3 3 3 3
赵六 1 1 1 1

将分组传给变量

In [30]:

classGroup = df.groupby('name')
classGroup

Out[30]:


In [34]:

classGroup.mean()  # 最常用
classGroup.size()  # 最常用
classGroup.sum()

Out[34]:

chinese math english
name
张三 18 82 68
李四 116 122 138
王五 176 126 248
赵六 94 58 64

如果不想使用分组列作为索引,设置参数as_index=False

In [35]:

df.groupby('name', as_index=False).mean()

Out[35]:

name chinese math english
0 张三 18.000000 82.0 68.000000
1 李四 58.000000 61.0 69.000000
2 王五 58.666667 42.0 82.666667
3 赵六 94.000000 58.0 64.000000

上面是以单列为基准分组,聚合单列

下面是:

  • 多列分组
  • 多列聚合

同时以多列为基准分组

多列分组

In [37]:

df

Out[37]:

name chinese math english test
0 张三 18 82 68
1 李四 53 63 52
2 王五 67 41 90
3 李四 63 59 86
4 王五 39 46 60
5 王五 70 39 98
6 赵六 94 58 64

In [36]:

df.groupby('name').mean()

Out[36]:

chinese math english
name
张三 18.000000 82.0 68.000000
李四 58.000000 61.0 69.000000
王五 58.666667 42.0 82.666667
赵六 94.000000 58.0 64.000000

In [40]:

x2 = df.groupby(['name', 'test']).mean()
x2

Out[40]:

image.png

In [43]:

x2.columns
x2.index

Out[43]:

MultiIndex(levels=[['张三', '李四', '王五', '赵六'], ['一', '三', '二']],
           labels=[[0, 1, 1, 2, 2, 2, 3], [0, 0, 2, 0, 1, 2, 0]],
           names=['name', 'test'])

In [39]:

# 给多列做分组,不将分组列作为索引
df.groupby(['test', 'name'], as_index=False).mean()

Out[39]:

test name chinese math english
0 张三 18 82 68
1 李四 53 63 52
2 王五 67 41 90
3 赵六 94 58 64
4 王五 70 39 98
5 李四 63 59 86
6 王五 39 46 60

多列聚合

对于大数据集,很可能只需要对部分列进行聚合

下列三种写法结果一样

  • 分组聚合参数,传入标量形式的单个列名,返回Series
  • 分组聚合参数,传入列表或数组,返回DataFrame(默认传入所有列)

In [44]:

df

Out[44]:

name chinese math english test
0 张三 18 82 68
1 李四 53 63 52
2 王五 67 41 90
3 李四 63 59 86
4 王五 39 46 60
5 王五 70 39 98
6 赵六 94 58 64

对除分组基准列以外的所有列进行聚合

In [45]:

df.groupby('name').sum()

Out[45]:

chinese math english
name
张三 18 82 68
李四 116 122 138
王五 176 126 248
赵六 94 58 64

分组后,只对 chinese 列进行聚合

In [47]:

# 方法1:对所有列进行聚合后,抽取需要的列
# 效率低(会运算所有列),不推荐
df.groupby('name').sum()['chinese']

Out[47]:

name
张三     18
李四    116
王五    176
赵六     94
Name: chinese, dtype: int64

In [50]:

# 方法2:抽出聚合列,和分组基准列,单独运算
# 效率高,但写着麻烦
df['name']
df['chinese']

# 传入标量或列名,返回Series
df['chinese'].groupby(df['name']).sum()

Out[50]:

name
张三     18
李四    116
王五    176
赵六     94
Name: chinese, dtype: int64

In [52]:

# 方法3:分组后指定某列进行聚合,书写简单,效率高,推荐**********************
# 是上面写法的简写(语法糖)
df.groupby('name')['chinese'].sum()

Out[52]:

name
张三     18
李四    116
王五    176
赵六     94
Name: chinese, dtype: int64

多列聚合

In [54]:

df.groupby('name')['chinese', 'math'].sum()

Out[54]:

chinese math
name
张三 18 82
李四 116 122
王五 176 126
赵六 94 58

聚合列,传入参数不是单值,而是列表或数组,返回DataFrame

In [58]:

df.groupby('name')[['chinese']].mean()

df[['chinese']].groupby(df['name']).mean()
df.groupby('name').mean()[['chinese']]

Out[58]:

chinese
name
张三 18.000000
李四 58.000000
王五 58.666667
赵六 94.000000

你可能感兴趣的:(Pandas分组聚合基础)