Skip to main content

CP08基于pandas实现分组聚合

阅读:-


我们都知道数据处理的四个层次是从,storge-data-information-intelligence, 而大部分的应用都集中在 data-information 的应用中,而分组聚合就是最基础的一种从 data 到 information 的处理过程。

8 Pandas-分组聚合

8.1 用例故事

在报表分析中,有一个非常常见的处理,是将多条有关联的记录,合并为 1 条记录,这个也就是在信息科学中常见的从 data 到 information 的处理过程,是最基础的数据处理模式,相关的处理模型见下图:

1587351351901

图 8-1 分组聚合的模型

8.1.1 应用故事

在5G时代,物联网技术广泛的流行,很多传统的行业的管理效率获得了很大的提升。因此我们就有机会获得很多数据,并需要将数据进行一些必要的归一化处理。

1587351388122

下面我们就举一个气象专业的例子, 假设在青年路地区,将这个地区划分了多个栅格,我们在每个栅格中放置一个气象站。

在某些情况下,为了节省气象站的电池消耗,我们可以将气象站的数据上报模式修改为随机上报模式,且上报的格式比较简单,不一定携带站点 id 和日期的信息。相关的数据结构见下图:

1587351491276

图 8-1 简化的温度数据上报模式

在简化的模式下,我们仅仅会得到气象站的经纬度数据Xserial,Yserial, 需要将经纬度数据合并为地理化化数据[Xserial,Yserial]

然后利用进行两步操作

  1. 将地理化坐标[Xserial,Yserial] 相同的记录进行分组。

  2. 将同一组内的多条记录的温度采样点数,低温采样点数进行聚合操作,聚合的算法是加法,大概的意涵是:

    假设按照地理化坐标[Xserial,Yserial]分组后,每一组中有 N 条记录。

    聚合(温度采样点数)=sum(温度采样点数 1+温度采样点数 2+… 温度采样点数 N);

    聚合(温度采样点数)= sum(低温采样点数 1+低温采样点数 2+… 低温采样点数 N)

经过这样的处理以后,就实现了将多条采样记录合并为 1 条记录的目的,这样分析相关的数据以后,经更加方便了。

经过整合以后的记录见下图:

1587351534682

8.1.2 用例描述

  1. 用户输入期待处理的文件路径,输出结果文件的,相关的信息结构

[ 输入文件绝对路径,输出文件绝对路径]

举例如下:[D:\PAE\grid.xlsx, D:\PAE\group-geo-grid.xlsx]

  1. 程序读取 grid.xlsx 文件,基于 pandas 转换为内存中的 dataframe,成为一个 Data set 的格式,命名为 DF1。

  2. 程序根据入参中“输出文件绝对路径”,创建一个输出结果 gropu-geo-grid.xlsx 文件的句柄。;

  3. 应用程序对 Data set 的表头进行扩展,增加一列,名字分别为

字段 1:X-Y:代表栅格的归一化坐标信息,是一个字符串结构。

  1. 应用程序针对 Dataframe 中的 字段 X-Y 进行分组操作,并对字段“温度采样次数“和”低温采样点数“ 进行聚合操作,聚合的算法是 sum,就是将相关的数值进行相加,其中数值为整型数据。

处理完毕以后,将生成一个新的DF2

  1. 应用程序将内存中的 data set,也就是新生成的 DF2, 写入输出结果 xlsx 文件的句柄, 相关文件决对路径来自输入数据。

举例:D:\PAE\group-geo-grid.xlsx

  1. 应用程序返回程序执行响应 [ 执行结果,输出结果文件信息]

其中执行结果:0 成功 1 失败

输出结果文件信息:提供输出结果文件的决对路径,举例如下:

举例:D:\PAE\group-geo-grid.xlsx

8.1.3 IPO 分析

详细 IPO 分析见用例模型。

8.2 用例约束

  1. python 使用 python3

2.文件读写使用 pandas 组件

3.数据操作使用 pandas 组件

8.3 设计方案简介

8.3.1 设计要点

应用分组聚合

8.3.2 调用关系

1587351672720

8.3.3 流穿越

  1. new_data = pd.read_excel(input_path,sheet_name=“Sheet1”)

1587351693672

2.合并新字段

new_data["x-y"]= new_data["Xserial"].map(str)+"-"+new_data["Yserial"].map(str)

1587351809191

3、分组聚合操作

res=new_data.groupby(["Xserial","Yserial","x-y"]).agg({"温度采样次数":"sum","低温采样点数":"sum"})

1587352111308

  1. 写入本地

1587352175553

8.4 设计方案详解

8.4.1 领域对象模型

1587352271394

图 8-1 用于分组聚合的领域对象模型

从上图可见,本用例中,主要包括 2 步操作:

1.向新生成的 DF 中,增加一个新的字段 X-Y。

2.根据字段 X-Y,进行分组聚合操作。

8.4.2 关键知识点

分组-聚合处理1、字段拼接str 数据类型合并
2、分组聚合操作数据分组,合并
使用 pandas 读/写 exclepd.read_excel()/写入
更改 df 一列的数据类型Df.map()速率有提升

8.4.3 字段拼接,df-str 属性

8.4.3.1 应用目的

根据实际应用需求,需要对 df 中部分 data 进行过滤以便得到 information。

为什么要用 str 属性?

文本数据也就是我们常说的字符串,Pandas 为 Series 提供了属性,通过它可以方便的对每个元素进行操作。

8.4.3.2 语法说明

Df.str

8.4.3.3 case 举例

1 新建一个 df

1587352350660

1587352371697

2 方案一,通常方案 map 与 apply

1587352411696

注此处报错无法运行,因为存在空值为 float 属性,np.nan

异常信息如下:

1587352455521

3、 方案二,str 方法

1587352491204

1587352502049

8.4.3.4 注意事项

文本数据也就是我们常说的字符串,Pandas 为 Series 提供了属性,通过它可以方便的对每个元素进行操作。

8.4.4 分组聚合操作

8.4.4.1 应用目的

Information 提取,从众多 data 过滤所需的信息

8.4.4.2 语法说明

Df.Groupby().add()

1587352549802

8.4.4.3 case 举例

1、分组聚合模型图

1587352574322

2、新建一个 df

1587352590896

3. 进行分组聚合

1587353368612

4、 自定义聚合函数

1587353389378

通过上面的例子我们可以看到,通过 apply 函数也可以完成类似 for 循环的迭代,在 pandas 中尽可能使用 apply 函数来代替 for 循环迭代,以提高性能。

5、根据多个键进行分组和聚合

1587353414969

8.4.4.4 注意事项

分组聚合作为网优工作中的常用知识点,需要重点掌握,学会使用。

8.4.5 使用 pandas 读/写 excle

8.4.5.1 应用目的

Excel 是微软的经典之作,在日常工作中的数据整理、分析和可视化方面,有其独到的优势,尤其在你熟练应用了函数和数据透视等高级功能之后,Excel 可以大幅度提高你的工作效率。但如果数据量超大,Excel 的劣势也就随之而来,甚至因为内存溢出无法打开文件,后续的分析更是难上加难。那么,有什么更好的解决办法吗?工欲善其事,必先利其器,在这里我们介绍使用 Python 的 pandas 数据分析包来解决此问题。

Storage 阶段,data 的读取与 information 的存储。

8.4.5.2 语法说明

pd.read_excel(io, sheet_name=0, header=0, names=None, index_col=None,

              usecols=None, squeeze=False,dtype=None, engine=None,

              converters=None, true_values=None, false_values=None,

              skiprows=None, nrows=None, na_values=None, parse_dates=False,

              date_parser=None, thousands=None, comment=None, skipfooter=0,

              convert_float=True, **kwds)

8.4.5.3 case 举例

1、io,Excel 的存储路径

建议使用英文路径以及英文命名方式。

import pandas as pd

io = r'C:\Users\Administrator\Desktop\data.xlsx'
2、sheet_name,要读取的工作表名称

可以是整型数字、列表名或 SheetN,也可以是上述三种组成的列表。

整型数字:目标 sheet 所在的位置,以 0 为起始,比如 sheet_name = 1 代表第 2 个工作表。

data = pd.read_excel(io, sheet_name = 1)

data.head()

列表名:目标 sheet 的名称,中英文皆可。

data = pd.read_excel(io, sheet_name = '英超射手榜')

data.head()

1587353465558

SheetN:代表第 N 个 sheet,S 要大写,注意与整型数字的区别。

data = pd.read_excel(io, sheet_name = 'Sheet5')

data.head()

1587353482990

组合列表: sheet_name = [0, ‘英超射手榜’, ‘Sheet4’],代表读取三个工作表,分别为第 1 个工作表、名为“英超射手榜”的工作表和第 4 个工作表。显然,Sheet4 未经重命名。

sheet_name 默认为 0,取 Excel 第一个工作表。如果读取多个工作表,则显示表格的字典。对于初学者而言,建议每次读取一个工作表,然后进行二次整合。

data = pd.read_excel(io, sheet_name = ['英超积分榜', '西甲积分榜'], nrows = 5)

sheet_name = ['英超积分榜', '西甲积分榜'] ,返回两个工作表组成的字典

data

1587353499992

3、header, 用哪一行作列名

默认为 0 ,如果设置为[0,1],则表示将前两行作为多重索引。

data = pd.read_excel(io, sheet_name = '英超积分榜', header = [0,1])

# 前两行作为列名。

data.head()

1587353519248

4、names, 自定义最终的列名

一般适用于 Excel 缺少列名,或者需要重新定义列名的情况。

注意:names 的长度必须和 Excel 列长度一致,否则会报错。

data = pd.read_excel(io, sheet_name = '英超射手榜',

                     names = ['rank','player','club','goal','common_goal','penalty'])

data.head()

1587353555810

5、index_col, 用作索引的列

可以是工作表列名称,如 index_col = ‘排名’;

可以是整型或整型列表,如 index_col = 0 或 [0, 1],如果选择多个列,则返回多重索引。

data = pd.read_excel(io, sheet_name = '英超射手榜', index_col = '排名')

data.head()

1587353584015

data = pd.read_excel(io, sheet_name = '英超射手榜', index_col = [0, 1])

data.head()

1587353602303

6、usecols,需要读取哪些列

可以使用整型,从 0 开始,如[0,2,3]

可以使用 Excel 传统的列名“A”、“B”等字母,如“A:C, E” =“A, B, C, E”,注意两边都包括。

usecols 可避免读取全量数据,而是以分析需求为导向选择特定数据,可以大幅提高效率。

data = pd.read_excel(io, sheet_name = '西甲射手榜', usecols = [0, 1, 3])

data.head()

1587353628623

data = pd.read_excel(io, sheet_name = '西甲射手榜', usecols = 'A:C, E')

data.head()

1587353645545

7、squeeze,当数据仅包含一列

squeeze 为 True 时,返回 Series,反之返回 DataFrame。

data = pd.read_excel(io, sheet_name = 'squeeze', squeeze = True)

data.head()

1587353757219

data = pd.read_excel(io, sheet_name = 'squeeze', squeeze = False)

data.head()

1587353773854

8、converters ,强制规定列数据类型
converters = {'排名': str, '场次': int}, 将“排名”列数据类型强制规定为字符串(pandas默认将文本类的数据读取为整型),“场次”列强制规定为整型;

主要用途:保留以文本形式存储的数字。

data = pd.read_excel(io, sheet_name = 'converters')

data['排名'].dtype

data = pd.read_excel(io, sheet_name = 'converters', converters = {'排名': str, '场次': float})

data['排名'].dtype

1587353795131

1587353814850

9、skiprows,跳过特定行

skiprows= n, 跳过前 n 行; skiprows = [a, b, c],跳过第 a+1,b+1,c+1 行(索引从 0 开始);

使用 skiprows 后,有可能首行(即列名)也会被跳过。

data = pd.read_excel(io, sheet_name = '英超射手榜', skiprows = [1,2,3])

# 跳过第 2,3,4 行数据(索引从 0 开始,包括列名)

data.head()

1587353836285

data = pd.read_excel(io, sheet_name = '英超射手榜', skiprows = 3)

data.head()

1587353855048

10、nrows ,需要读取的行数

如果只想了解 Excel 的列名及概况,不必读取全量数据,nrows 会十分有用。

data = pd.read_excel(io, sheet_name = '英超射手榜', nrows = 10)

1587353875027

11、skipfooter , 跳过末尾 n 行
data = pd.read_excel(r'C:\Users\Administrator\Desktop\data.xlsx' ,

                 sheet_name = '英超射手榜', skipfooter = 43)

# skipfooter = 43, 跳过末尾 43 行(索引从 0 开始)

1587353893060

1.4.5.4 注意事项

Excel 没有追加模式,可以用下图方式写入文件

1587354056608

8.4.6 更改 df 一列的数据类型

8.4.6.1 应用目的

归一化数据类型,便于对 data 进行操作,提取信息

8.4.6.2 语法说明

df[“x 列”].map(str)

转换 df 二维数组,第 x 列数据类型为字符串

8.4.6.3 case 举例

1587354094160

Df 数据如下:

1587355197783

对 xy 转换格式后相加:

1587355215331

不转换格式直接相加,会因为 int 没有拼接属性而报错。

1587355235717

8.4.6.4 注意事项

格式归一化,是数据处理的第一步。

8.5 总结

在这一章中,我们训练了数据报表中,非常常见的分组聚合操作,依托pandas,可以非常容易的处理这一类操作。

掌握了这一章,智慧的你就实现了从data到information的入门了。

分享到微博
Starter
MicroServ
Tutorials
Report
Blog