人工智能 Day06 pandas库进阶

1.处理缺失数据

总体流程是这样的,

 归根在于如何处理NAN,接下来详细赘述

1.1. 处理缺失值的相关函数
  • 判断缺失值
    • pd.isnull(df):用于判断 DataFrame df 中的元素是否为缺失值(NaN ),返回一个与df 形状相同的布尔型 DataFrame,元素为True 表示对应位置是缺失值。
    • pd.notnull(df):与pd.isnull(df) 相反,判断 DataFrame df 中的元素是否不是缺失值,返回布尔型 DataFrame,元素为True 表示对应位置不是缺失值 。
    • 之后利用np.all()或者np.any就可以知道数据中是否存在NaN。
  • 删除缺失值
    • dropna(axis='rows'):用于删除存在缺失值的行(当axis='rows' 时 )或列(当axis='columns' 时 )。默认axis='rows' ,不会修改原数据,需要接收返回值。例如new_df = df.dropna() ,将返回删除缺失值行后的新 DataFrame。
  • 填充缺失值
    • fillna(value, inplace=False):用指定的value 填充缺失值。inplace=False (默认 )时,不修改原数据,返回填充后的新对象;inplace=True 时,直接在原数据上进行填充修改。例如df.fillna(0, inplace=True) ,将把df 中的缺失值都填充为 0 。
  • 替换数据
    • replace(to_replace, value):用于替换数据。to_replace 是要被替换的值,value 是替换后的值。例如df.replace('?', np.nan) ,将把df 中所有的'?' 替换为NaN 。
1.2. 电影数据的缺失值处理示例
  • 判断缺失值是否存在
import pandas as pd
# 读取电影数据
movie = pd.read_csv("./data/IMDB-Movie-Data.csv")
# 使用pd.notnull判断
not_null_result = pd.notnull(movie)
#返回一个和movie的shape一样的数组,全是布尔型,True为不空,False为空,
#只要结合np.all即可判断是否有空,如果有就是返回False
np.all(not_null_result)
# 使用pd.isnull判断#另一种方法
is_null_result = pd.isnull(movie)
#返回一个和movie的shape一样的数组,全是布尔型,True为不空,False为空,
#只要结合np.any即可判断是否有空,如果有就是返回True
  • 存在缺失值且为np.nan时的处理
    • 删除缺失值
# 不修改原数据
new_movie = movie.dropna()
# 也可重新赋值给原变量
movie = movie.dropna()
  • 填充缺失值
# 填充'Revenue (Millions)'列的缺失值为该列均值
movie['Revenue (Millions)'].fillna(movie['Revenue (Millions)'].mean(), inplace=True)
# 遍历填充所有存在缺失值的列
for i in movie.columns:if np.all(pd.notnull(movie[i])) == False:movie[i].fillna(movie[i].mean(), inplace=True)
  • 缺失值不是np.nan时的处理
import pandas as pd
import numpy as np
# 读取数据(假设数据中有'?'表示缺失值)
wis = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer")
# 替换'?'为np.nan
wis = wis.replace(to_replace='?', value=np.nan)
# 后续再进行缺失值填充等操作,例如填充某列缺失值为均值
wis['column_name'].fillna(wis['column_name'].mean(), inplace=True)
1.3. 处理缺失值的步骤总结
  1. 统一缺失值形式:若存在缺失值但不是np.nan 的形式,使用data.replace(to_replace, value=np.nan) 将其替换为np.nan 。
  2. 判断是否存在缺失值:使用np.all(pd.notnull(data)) ,若结果为True ,表示不存在缺失值,不做处理;若为False ,表示存在缺失值,继续下一步。
  3. 填充缺失值:使用统计学指标值(如均值mean、中位数median等 )对缺失值进行填充,如data['column_name'].fillna(data['column_name'].mean(), inplace=True) 。

2.数据的离散化

2.1. 为什么要离散化

连续属性离散化目的是简化数据结构,减少给定连续属性值个数,常作为数据挖掘工具。比如在分析用户年龄与消费习惯时,年龄是连续属性,将年龄离散化为儿童、青年、中年、老年等区间,可更方便分析不同年龄段消费特征。

2.2. 什么是数据的离散化

连续属性离散化是在连续属性值域上划分若干离散区间,用不同符号或整数值代表落在各子区间的属性值。例如原始身高数据 165, 174, 160, 180, 159, 163, 192, 184 ,按 150 - 165, 165 - 180, 180 - 195 划分区间,可标记为矮、中、高类别。

2.3. 具体实现
  • 读取股票数据
import pandas as pd
# 读取股票数据
data = pd.read_csv("./data/stock_day.csv")
# 筛选出p_change数据
p_change = data['p_change']

此代码先读取股票 CSV 文件数据,再提取出涨跌幅数据p_change ,为后续离散化操作准备数据。

  • 将股票涨跌幅数据进行分组
    • 等频分组(qcut )
# 自行分组,将数据分为10组
qcut = pd.qcut(p_change, 10)
# 计算分到每个组数据个数
qcut.value_counts()

pd.qcut(data, q)中,data是要分组的数据(这里是p_change ),q是要划分的组数(这里为 10 ),它会使每组数据数量尽量相等。value_counts()用于统计每组数据个数,经常结合离散化一起使用

  • 自定义区间分组(cut )
# 自己指定分组区间
bins = [-100, -7, -5, -3, 0, 3, 5, 7, 100]
p_counts = pd.cut(p_change, bins)

pd.cut(data, bins)中,data是数据,bins是自定义区间边界列表(这里bins指定了具体区间 ),按此区间对数据进行分组。也经常结合value_counts()一起使用。

现在我们就通过统计个数得到了一下形式

接下来为了精准的表示每个样本在那个区间可以使用一下编码(one-hot/哑变量)

  • 股票涨跌幅分组数据变成 one - hot 编码
    • one - hot 编码概念:把每个类别生成一个布尔列,每个样本只有一列取值为 1 ,其他为 0 ,又称热编码。例如类别有 Human、Penguin、Octopus、Alien ,编码后每个样本对应这些类别列,只有所属类别列值为 1 。这样又多了四个特征,每个样本表示唯一。
    • 实现代码
# 得出one-hot编码矩阵
dummies = pd.get_dummies(p_counts, prefix="rise")

pandas.get_dummies(data, prefix=None)中,data可以是类似数组、Series 或 DataFrame(这里是分组后的p_counts ),prefix是分组名字(这里为rise ),生成 one - hot 编码矩阵,方便后续机器学习模型处理。这是最后结果。

3.数据的合并

如果数据由多张表构成,需要进行数据合并

1. pd.concat实现数据合并
  • 函数语法及参数
    pd.concat(objs, axis=0, join='outer', ignore_index=False)
    • objs:必填参数,是一个由 DataFrame 或 Series 组成的列表,如[data1, data2] ,表示要合并的对象。
    • axis:可选参数,用于指定合并的轴方向。axis=0(默认值)表示按列索引合并(纵向合并 ),即上下拼接;axis=1表示按行索引合并(横向合并 ),即左右拼接。
    • join:可选参数,指定合并时的连接方式,有'outer'(默认值,取并集 )和'inner'(取交集 )两种。
    • ignore_index:可选参数,布尔值,默认为False 。若为True ,合并后将重新生成行索引。
  • 代码示例
2. pd.merge实现数据合并
  • 函数语法及参数
    pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None)
    • left:必填参数,第一个 DataFrame。
    • right:必填参数,第二个 DataFrame。
    • how:可选参数,指定连接方式,常见取值有:
      • 'inner':内连接(默认值),使用左右 DataFrame 键的交集。
      • 'left':左连接,使用左 DataFrame 的键。
      • 'right':右连接,使用右 DataFrame 的键。
      • 'outer':外连接,使用左右 DataFrame 键的并集。
    • on:可选参数,指定用于合并的共同键列。要求左右 DataFrame 都存在该列
    • left_on:可选参数,指定左 DataFrame 用于合并的键列。
    • right_on:可选参数,指定右 DataFrame 用于合并的键列。
  • 代码示例
import pandas as pd
left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],'key2': ['K0', 'K1', 'K0', 'K1'],'A': ['A0', 'A1', 'A2', 'A3'],'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],'key2': ['K0', 'K0', 'K0', 'K0'],'C': ['C0', 'C1', 'C2', 'C3'],'D': ['D0', 'D1', 'D2', 'D3']})
# 默认内连接
result_inner = pd.merge(left, right, on=['key1', 'key2'])
# 左连接
result_left = pd.merge(left, right, how='left', on=['key1', 'key2'])
# 右连接
result_right = pd.merge(left, right, how='right', on=['key1', 'key2'])
print("内连接结果:\n", result_inner)
print("左连接结果:\n", result_left)
print("右连接结果:\n", result_right)

此代码先创建了两个 DataFrame left 和right ,然后分别展示了内连接、左连接和右连接的合并结果。

拓展一下连接:

其实和数据库的一样,内连接就是筛选数据,没有相同的键值的数据被排除

外连接就是分别遍历左右表,如果另一个表有相同的键值的全部列出来,直到左右两表被全部遍历完。左连接和右连接其实是特殊的外连接,就是只遍历左表或者右表。

4.交叉表和透视表(交叉表是一列特征在另一列特征上的数量,透视表是占比但其实进过计算交叉表除以和还是透视表) 

 案例分析

1 数据准备
  • 提取日期对应的星期数
import pandas as pd
import numpy as np
# 假设data是包含股票数据的DataFrame,其索引为日期
date = pd.to_datetime(data.index).weekday
data['week'] = date

pd.to_datetime() 将索引的日期字符串转换为日期时间格式,.weekday 方法获取对应的星期数(0 代表星期一,1 代表星期二,以此类推 ),并将其作为新列week 添加到data 中。

内容拆解:

47行数据不可以用,所以要转化为可以使用的数据,接下来就可以取出对应的年月日了

  • 将涨跌幅数据分类
data['posi_neg'] = np.where(data['p_change'] > 0, 1, 0)

np.where() 函数根据条件判断,当data['p_change'] 大于 0 时,对应位置赋值为 1 (代表涨幅为正 ),否则赋值为 0 (代表涨幅为负或持平 ),并将结果存储在新列posi_neg 中,用来形成交叉表。

  • 交叉表计算
count = pd.crosstab(data['week'], data['posi_neg'])

pd.crosstab() 函数根据data['week'] 和data['posi_neg'] 生成交叉表,统计每个星期数下涨跌幅为正(1 )和为负或持平(0 )的天数。

结果为现在就是交叉表了,我们展示占比(也就是透视表)

  • 计算比例
sum = count.sum(axis=1).astype(np.float32)
pro = count.div(sum, axis=0)

count.sum(axis=1) 计算交叉表中每一行(每个星期数 )的总数,.astype(np.float32) 将数据类型转换为 32 位浮点数。count.div(sum, axis=0) 进行除法运算,axis=0 表示按列方向,将交叉表的每一列除以对应的行总数,得到每个星期数下涨跌幅为正和为负或持平的比例。pro如下图:

2 查看效果
import matplotlib.pyplot as plt
pro.plot(kind='bar', stacked=True)
plt.show()

pro.plot(kind='bar', stacked=True) 使用matplotlib 库绘制堆叠柱状图,kind='bar' 指定为柱状图类型,stacked=True 表示堆叠显示,便于直观对比每个星期数下涨跌幅正负的比例情况。plt.show() 显示绘制的图形。如下图

 如不堆叠显示,图会如下:

3.其实我们可以直接得到一列数据的占比,使用透视表即可:

2.3 使用pivot_table(透视表)实现

  • 函数语法及参数
    pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False)
    • data:必填参数,为要操作的 DataFrame 对象,这里是包含股票数据及相关衍生列(如weekp_n等 )的data 。
    • values:可选参数,接收列名组成的列表,指定要进行聚合计算的列。这里['posi_neg']["p_n"] 表示对涨跌幅正负标记列进行操作。
    • index:可选参数,指定用于分组的索引列,这里'week' 表示按星期数分组。
    • columns:可选参数,用于指定列分组依据,若不指定则不进行列方向分组。
    • aggfunc:可选参数,默认'mean' ,用于指定聚合函数。常见的有'sum'(求和)、'count'(计数)等。这里默认求均值,对于 0 和 1 组成的涨跌幅正负标记列,均值就相当于涨幅为正的比例。
    • fill_value:可选参数,用于指定填充缺失值的值。
    • margins:可选参数,布尔值,默认为False ,若为True 会添加总计行和总计列。
  • 代码示例
import pandas as pd
# 假设data是包含股票数据及相关衍生列(如week、p_n等)的DataFrame
result = data.pivot_table(["p_n"], index="week")
print(result)

此代码通过pivot_table 函数,以week 列为索引,对p_n 列(涨跌幅正负标记列 )进行聚合操作(默认求均值 ),直接得到每个星期数下涨幅为正的比例,相较于之前交叉表计算等步骤更为简洁。结果如下:

5.分组与聚合(两个类似于数据库,经常结合在一起使用,只有分组没有聚合只会返回一个对象没有意义。)

一个简单的图:

分组 API

DataFrame.groupby函数
  • 函数语法及参数
    DataFrame.groupby(key, as_index=True)
    • key:必填参数,用于指定分组的列数据,可以是单个列名,也可以是列名组成的列表。比如['color'] ,表示按color列进行分组。
    • as_index:可选参数,布尔值,默认为True 。当as_index=True 时,分组的键(这里是color列的值 )会作为结果的索引;当as_index=False 时,分组的键会作为结果的一列保留,数据结构保持不变。
  • 案例讲解
    • 数据准备
import pandas as pd
col = pd.DataFrame({'color': ['white','red', 'green','red', 'green'],'object': ['pen', 'pencil', 'pencil', 'ashtray', 'pen'],'price1': [5.56, 4.20, 1.30, 0.56, 2.75],'price2': [4.75, 4.12, 1.60, 0.75, 3.15]})

此代码创建了一个 DataFrame col ,包含color(颜色)、object(物品)、price1price2(价格)四列数据。

  • 分组聚合操作
    • as_index=True 情况(默认 )
# 分组,求平均值
col.groupby(['color'])['price1'].mean()
col['price1'].groupby(col['color']).mean()

这两种写法等价,都是按color列对price1列进行分组并求平均值。运行后,color列的值作为索引,得到不同颜色对应的price1平均值:

color
green    2.025
red      2.380
white    5.560
Name: price1, dtype: float64
  • as_index=False 情况
col.groupby(['color'], as_index=False)['price1'].mean()

此代码按color列对price1列进行分组并求平均值,同时设置as_index=False ,此时color列作为结果的一列保留,得到:

  color  price1
0 green  2.025
1   red  2.380
2 white  5.560

通过groupby函数结合聚合函数(如mean ),可以方便地对数据进行分组聚合操作,分析不同组别的数据特征 。

为什么要在group后边加上具体的列呢?

明确聚合对象

groupby 函数实现分组后,需要对特定的列进行聚合计算(这里是求平均值,使用mean 函数 )。col 这个 DataFrame 可能包含多列数据(如案例中还有objectprice2 等列 ),通过指定['price1'] ,就明确告诉程序是要对price1 这一列的数据进行聚合操作。如果不指定,程序就不知道具体要对哪列数据进行后续的聚合计算,会引发错误。

符合逻辑操作流程

分组聚合操作的逻辑是先分组,然后对组内的某列或某些列数据进行聚合。比如在这个案例中,我们想知道不同颜色对应的price1 价格的平均值,所以要指定price1 列。如果我们想分析price2 列,就需要指定['price2'] ,如col.groupby(['color'])['price2'].mean() 。

注意,仔细观察两种方法的不同之处,group里的代码一个直接用列名一个不能:

col['price1'].groupby(col['color']).mean() 这种针对 Series 对象进行groupby 操作的情境下,不能直接用列名。

因为col['price1'] 已经是一个 Series 对象,当对它调用groupby 方法时,groupby 函数期望传入一个与该 Series 长度一致的可迭代对象(通常也是一个 Series )来确定分组规则。如果直接写列名,比如col['price1'].groupby('color').mean() ,程序会报错,因为'color' 只是一个字符串,不是与col['price1'] 长度相同的可迭代对象,无法明确分组逻辑。

 

而在基于 DataFrame 进行groupby 操作时,像col.groupby(['color'])['price1'].mean() ,可以直接用列名(以列表形式 )来指定分组依据,这是因为 DataFrame 的groupby 方法有相应的机制去识别和处理列名列表作为分组键

当group中分组依据是一个列表的时候就好像是先按第一个分,然后一次分组:

首先这张图,表示了如果使用汇总聚合函数,并不需要指定列,因为只是统计个数的话不需要明确。

第二展示了列表分组规律

6.整体电影数据案例

关于问题1 很简单

关于问题2:

因为只用pandas绘图简单无法进行刻度的设置,注意这里数据是加了.values,因为如果不加他是一个series的格式,这样有索引,你需要用值所以是.values所以需要用matplotlib进行绘图结果如下:

 但是发现刻度不对,我们需要对上,所以可以将数据的max与min之间的数分21个(因为是设置了20组,需要21个数),用linspace生成等距的数即可。

关于问题3 

我们首先要知道所有电影的种类(因为每个电影种类很多且有重复,可以使用unique来进行去重)

接着生成一个全0列表行数为电影数列数为电影种类,之后我们可以循环每个电影对应的种类,如果是某个类型即为1,最后按列求和就可以知道具体有多少了

解释一下那个分割:首先如果不用按逗号分割列表里每个元素是这样的:

类型之间按逗号分割

所以要按逗号分割于是可以单独提出类型列表,因为i.split返回值就是列表,所以组成了列表嵌套

之后使用双循坏就可以取出每个值了,然后在去重即可,如下图:

然后生成一个按电影为行,按类型为列的dataframe即可

之后循坏完毕按列求和即可

之后排序绘图即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/34652.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Tools】Visual Studio Code安装保姆级教程(2025版)

00. 目录 文章目录 00. 目录01. Visual Studio Code概述02. Visual Studio Code下载03. Visual Studio Code安装04. Visual Studio Code配置05. 附录 01. Visual Studio Code概述 Visual Studio Code(简称 VS Code)是由微软开发的一款免费、开源且跨平台…

14.使用各种读写包操作 Excel 文件:辅助模块

一 各种读写包 这些是 pandas 在底层使用的各种读写包。无须安装 pandas,直接使用这些读写包就能够读写 Excel 工作簿。可以尽可能地使用 pandas 来解决这类问题,只在 pandas 没有提供你所需要的功能时才用到读写包。 表中没有 xlwings ,因为…

AI赋能实时安全背带监测解决方案

背景:安全背带检测的行业刚需与技术痛点 在建筑施工、石油化工、仓储物流等高危行业中,安全背带是保障作业人员生命安全的最后一道防线。据统计,超过30%的高空坠落事故与未正确佩戴安全背带直接相关。传统依赖人工巡检的监督方式存在效率低、…

神聖的綫性代數速成例題2. 行列式的性質

性質 1:行列式與它的轉置行列式相等: 設為行列式,為其轉置行列式,則。 性質 2:交換行列式的兩行 (列),行列式變號: 若行列式經過交換第行和第行得到行列式,則。 性質 3&#xff…

大模型推理 memory bandwidth bound (3) - MLA

系列文章目录 大模型推理 & memory bandwidth bound (1) - 性能瓶颈与优化概述 大模型推理 & memory bandwidth bound (2) - Multi-Query Attention 大模型推理 & memory bandwidth bound (3) - MLA 文章目录 系列文章目录前言一、原理1.低秩压缩 & 动机2.矩阵…

CTP开发爬坑指北(九)

CTP API开发中有很多需要注意的小细节,稍有不慎就会出问题,不然,轻则表现与预期不符,重则程序崩溃影响策略盈利。本系列将容易遇到的坑列出来,以供开发时参考,如有疑义之处,欢迎指正。 在国内期…

python_巨潮年报pdf下载

目录 前置: 步骤: step one: pip安装必要包,获取年报url列表 step two: 将查看url列表转换为pdf url step three: 多进程下载pdf 前置: 1 了解一些股票的基本面需要看历年年报,在巨潮一个个下载比较费时间&…

量化交易backtrader实践(五)_策略综合篇(3)_经典策略复盘

01_经典策略复盘 在某款股票软件手机版App上,有一项“复盘”的功能,这个功能很强大,它能把这支股票近1年的走势,用设置好的六个策略去回测,得到每个策略的近一年的收益率,并做了从最好到最差的排序。这就能…

蓝桥与力扣刷题(蓝桥 字符统计)

题目:给定一个只包含大写字母的字符出 S, 请你输出其中出现次数最多的字符。如果有多个字母均出现了最多次, 按字母表顺序依次输出所有这些字母。 输入格式 一个只包含大写字母的字等串 S. 输出格式 若干个大写字母,代表答案。 样例输入 BABBACAC样…

protobuf安装

安装 github官方链接 https://github.com/protocolbuffers/protobuf/ 以protobuf21为例 https://github.com/protocolbuffers/protobuf/releases/download/v21.11/protobuf-all-21.11.zip windows 解压好文件夹后,使用cmake,vs,qt creator等工具打开该项目,进行编译,编译需…

Compose 实践与探索八 —— LayoutModifier 解析

前面几节讲的 Modifier 都是起辅助作用的,比如 Modifier 的伴生对象、CombinedModifier、 ComposedModifier 以及几乎所有 Modifier 的父接口 Modifier.Element。本篇我们开始讲具有直接功效的 Modifier,分为几个大类:LayoutModifier、DrawMo…

stl之string的详解

一,string定义的方式 ,string定义了多种函数重载的方式,常用的构造函数如下: string(); string(const string& str); string(const string& str, size_t pos, size_t len npos); string(const char* s); string(const …

Leetcode-131.Palindrome Partitioning [C++][Java]

目录 一、题目描述 二、解题思路 【C】 【Java】 Leetcode-131.Palindrome Partitioninghttps://leetcode.com/problems/palindrome-partitioning/description/131. 分割回文串 - 力扣(LeetCode)131. 分割回文串 - 给你一个字符串 s,请你…

InternVL:论文阅读 -- 多模态大模型(视觉语言模型)

更多内容:XiaoJ的知识星球 文章目录 InternVL: 扩展视觉基础模型与通用视觉语言任务对齐1.概述2.InternVL整体架构1)大型视觉编码器:InternViT-6B2)语言中间件:QLLaMA。3)训练策略(1&#xff09…

【AWS入门】AWS云计算简介

【AWS入门】AWS云计算简介 A Brief Introduction to AWS Cloud Computing By JacksonML 什么是云计算?云计算能干什么?我们如何利用云计算?云计算如何实现? 带着一系列问题,我将做一个普通布道者,引领广…

二分算法刷题

1. 初识 总结:二分算法题的细节非常多,容易写出死循环。使用算法的条件不一定是数组有序,而是具有“二断性”;模板三种后面会讲。 朴素二分二分查找左端点二分查找右端点 2. 朴素二分 题目链接:704. 二分查找 - 力扣…

itsdangerous加解密源码分析|BUG汇总

这是我这两天的思考 早知道密码学的课就不旷那么多了 纯个人见解 如需转载,标记出处 目录 一、官网介绍 二、事例代码 源码分析: 加密函数dump源码使用的函数如下: 解密 ​编辑 ​编辑 关于签名: 为什么这个数字签名没有…

深度解析React Native底层核心架构

React Native 工作原理深度解析 一、核心架构:三层异构协作体系 React Native 的跨平台能力源于其独特的 JS层-Shadow层-Native层 架构设计,三者在不同线程中协同工作: JS层 运行于JavaScriptCore(iOS)或Hermes&…

前端内存优化实战指南:从内存泄漏到性能巅峰

前端内存优化实战指南:从内存泄漏到性能巅峰 一、内存问题引发的场景 1.1 典型内存灾难现场 // 经典内存泄漏示例 const zombieElements new Set();function createLeak() {const div document.createElement(div);zombieElements.add(div); // 元素永不释放div…

【工作记录】pytest使用总结

1、 fixture夹具 可参考: python3.x中 pytest之fixture - 漂泊的小虎 - 博客园 fixture是指夹具(把用例夹在中间),它包括前置工作和后置工作,前置是用例代码的准备阶段,后置是用例执行之后的清理阶段,用…