Week 12
本周学习主要内容为Pandas剩余部分(自定义函数运算,分组聚合进阶,可视化,数据规整)、重塑和轴向旋转、透视表和交叉表、离散化
数据分析流程
软件开发流程:
- 需求分析
- 设计
- 编码
- 测试
数据分析流程:
- 基本流程
- 提出问题
- 准备数据 (1,2步现实中可能顺序颠倒)
- 分析数据
- 洞察结论
-
不断迭代
-
拓展流程
- 需求层:目标确定
- 数据层:
- 数据获取
- 数据规整(预处理,清洗)
- 清理 / 转换 / 合并 / 重塑
- 数据重构,特征工程
- 分析层:
- 描述性分析(对现有数据的理解更加深入)
> 构建指标(分组聚合旋转 / 透视表 / 交叉表)
> 数据可视化 - 探索性分析(可选,挖掘数据之下的信息,或预测未知数据)
> 建模分析
> 模型验证
> 迭代优化
- 描述性分析(对现有数据的理解更加深入)
- 输出层:
- 洞察结论,结果可视化,报告撰写,成果应用(宣讲,推动)
-
优化迭代
数据分析师日常工作:
业务性数据分析师
- 报表处理(数据规整)
- 指标计算
- 可视化
- 建模预测
综合:数据分析报告
数据分析报告书写套路
- 背景介绍
- 情况介绍(公司情况、接单情况)
- 数据介绍
- 需求(分析什么) - 数据工程:
- 数据获取:SQL、爬虫、买……
- 数据预处理:载入清洗,重构 - 数据分析
- 描述性分析:
> 指标计算(分组聚合旋转、透视表、交叉表)(反复迭代)
> 数据可视化(反复迭代)
- 探索性分析(建模预测),可选 - 结论
- 总结分析结果
- 意见建议
透视表(pivot_table)和交叉表(crosstable)
实现数据分析指标计算的常用操作:
交叉表 -> 透视表 -> 分组聚合旋转 -> 自定义函数 (狭窄到广泛的顺序)
- 交叉表就是聚合函数时len个数的透视表
- 透视表是由聚合函数是mean的分组旋转而成(分组/mean聚合/旋转)
- 分组聚合就是自定义函数的一种特定操作
越往底层书写越难,应用范围越广。越往上层书写越简单,应用范围越窄
透视表(pivot table)
-
是各种电子表格程序和数据分析软件中一种高级数据汇总表格形式
-
数据源表通常只包含行和列,经常有重复和无用之出现在各列下,因而导致源表不能传递有价值的信息。这是可以用[透视]方法调整元彪的布局用作更清晰的展示。
-
透视表是用来汇总其他表的数剧:
- 首先把源表分组,将不同值当作行(row)、列(column)和值(value)
- 然后对各组内数据做汇总操作如排序、平均、累加、计数等
-
这种动态将源表转换得到想要终表的旋转过程(pivoting),叫做透视表
-
透视表默认聚合函数为mean平均值
-
如果想使用非默认mean的其他的聚合函数,传给aggfun即可(传入函数名称或函数字符串)
-
如果使用count或者len可得到有关分组大小的交叉表(计数或频率)
-
传入值类型,一般为函数名字符串,函数名,numpy函数名:
- len
- ‘count’
- np.max (推荐)
衡量能否做数据分析项目的基准:
- 入门:用Pandas原生的pivot_table方法生成透视表
- 进阶:使用groupby和unstack配合手动构造透视表
乞丐版交叉表(1列数据的频度情况,只有一个维度,分组聚合实现)
#表格某一列所有内容的出现次数
t2.groupby(‘day’).size().sort_values(ascending=False)
t2.day.value_counts() #同上
常用的crosstab交叉表函数结构(2列数据的频度情况)
#常见参数:行索引,列索引,分项小计
pd.crosstab(tips.time,[tips.smoker,tips.day],margins=True)
常用的Pivot_table透视表函数结构
#常见参数:需要计算的列,行索引,列索引,分项小计(默认False),自定义计算函数(默认mean),缺失值填充
tips.pivot_table([‘tip_pct’,‘size’],index=[‘time’,‘day’],columns=‘smoker’,margins=True,aggfunc=len,fill_value=0)
#交叉表只要把aggfun参数值改为len即可
底层:使用分组聚合和轴向旋转实现透视表
#分组:行索引,列索引;郡治局和,行索引转为列索引;填充缺失值为0
tips.groupby([‘time’,‘day’,‘smoker’)[‘size’,‘tip_pct’].mean().unstack().fillna(0)
#交叉表只要把聚合函数由.mean()改为.size()即可
pivot_table 其他参数
- 传入margins=True添加分项小计
- 这将会添加标签为All的行和列,其值对应于单个等级中所有数据的分组统计
- All值为平均数:不单独考虑烟民与非烟民(All列),不单独考虑行分组两个级别中的任何单项(All行)
- All统计求的是所有行或所有列的平均值,不是透视表那几行几列的平均值
pivot和pivot_table的区别
- pivot_table转换后,如果表索引有重复值会聚合为一个输出,不会出错
- pivot转换后,如果表索引有重复值会直接出错(安全措施,如果需要重塑表又得100%防止数据无意中求均值,破坏数据)
- 如果数据不重复,pivot_table得到的结果和pivot一致
- pivot_table更常用
交叉表:crosstab
交叉表(cross-tabulation,简称crosstab)是一种用于计算分组频率的特殊透视表
- 透视表由分组后聚合函数为平均值的表旋转而成
- 交叉表就是聚合函数为个数的透视表
重塑和轴向旋转
有许多用于重新排列表格型数据的基础运算。这些函数也称作重塑(reshape)或轴向旋转(pivot)运算
数据重塑和轴向旋转操作:表示转换一个表格或向量的结构,使其适合于进一步分析
重塑层次化索引
层次化索引为DataFrame数据的重排任务提供了一种具有良好一致性的方式。主要功能有:
- stack():列转行,将数据的列索引“旋转”为行索引
- 少用,一般用于将DataFrame转为层次化Series用
- unstack():行转列,将数据的行索引“旋转”为列索引
- 常用:一般用于将层次化Series转为DataFrame
二者互为逆运算
注意:
- Series没有stack属性(因为Series没有列)
- 对DataFrame进行unstack操作时,作为旋转轴的级别将会成为结果中的最低级别
行转列:unstack将Series层次化索引顺时针旋转为列索引
-
对层次化索引的Series,可以用unstack将其重排为一个DataFrame
-
unstack默认操作的是最里层,stack也是,传入分层级别编号或name即可对其它级别进行unstack操作
转置
- 行列索引交换位置
data.unstack().unstack() #两次unstack转置完成,行列索引交换位置
data.T #转置快捷操作 同上
-------------------------------------
state Ohio Colorado
number
one 0 3
two 1 4
three 2 5
- 如果不是所有级别值都能在各分组中找到的话,unstack操作会引入缺失数据
- stack默认会滤除缺失数据,因此改运算可逆
表格的长宽转换(了解)
用分组聚合(groupby)和重塑(unstack)一般可以实现所有的数据重塑功能
表格长宽转换也是一种透视表操作
- df.pivot()
- 将一张长表转为多张宽表
- pd.melt()
- 将多张宽表转为一张长表
二者互为逆操作
把长格式转成宽格式:pivot()
将一列拆分为多列
- 1列值做行索引
- 一列值做列索引
- 剩下的值做表格值
多个时间序列数据通常是以所谓的“长格式”(long)或者“堆叠格式”(stacked)存储在数据库和CSV中的
将“宽格式”旋转成“长格式”
- 将多列合并为一列
- pivot的逆运算是pandas.melt
- 当使用pandas.melt,最好指明哪些列是分组指标
- 指定key列是唯一分组指标,其他列是数据值
- 他不是将一列转换到多个新的DataFrame,而是合并多个列成为一个,产生一个比输入长的DataFrame
Pandas相关内容
数据规整
数据规整的一般分类:
- 清理
- 转换
- 合并
- 重塑
Pandas分组聚合 - 进阶
本质上,groupby传入的数据并不是行索引或列索引,而是任意一个和数据结构对应的序列(布尔值序列、列表、数组、字典、Series)
- 根据列表做分组基准
- 列表值个数必须和表格行或列数对应
- 根据字典或Series
- 字典会对应替换表格的行或列索引,然后进行分组
- 根据函数(返回的结果)做分组基准
- 笔记字典或Series,函数是一种更原生的方法定义分组映射
- 任何被当作分组键的函数都会在各个索引值上被调用一次,其返回值就会被作为分组基准
- 根据层次化索引的级别做分组基准
- 要根据层次化索引的级别分组,使用level关键字传递级别序号或名字
- 按行分组
#按行分组
df.groupby('name').sum() #简写
df.groupby('name',axis=0).sum() #完整
#按行分组,自定义布尔数组做分组基准
ddd = [True,True,False,False,False,False,True]
df.groupby(ddd,axis=0).sum()
- 按列分组
- 使用列数据类型作为分组基准
df.groupby(df.dtypes,axis=1).sum() #手动将分组基准传入,结果同上 fff = ['object','int64','int64','int64','object'] df.groupby(fff,axis=1).sum()
- 使用字典按列分组
#假设一直列的分组关系,并希望根据分组计算列的和 mapping = {'a':'red','bc':'red','c':'blue','d':'blue','e':'red','f':'orange'} # 多写或少写不会执行,多了一个f,不会影响分组 people.groupby(mapping,axis=1).sum()
- 使用函数按列分组
people.groupby(len,axis=1).sum()
Pandas分组聚合 - 高级
自定义聚合方式
在分组聚合的split-apply-combine过程中,apply是核心,Python本身有高阶函数apply()来实现
自定义聚合方式:aggregate(),或agg()
之前的聚合方式,所有列只能应用一个相同的聚合函数
agg()自定义聚合方式的优势:
-
聚合参数是列表
- 对数据每列应用多个相同的聚合函数
-
聚合参数就是字典
- 对数据的每列应用一个或多个不同的聚合函数
-
聚合参数是自定义函数
- 对数据进行一些复杂操作
- 自定义聚合函数要比系统自带的、经过优化的函数慢得多
- 因为在构造中间分组数据是存在非常大的开销(函数调用、数据重排等)
自定义聚合方式可以:
每个列应用不同的聚合方式
一个列应用多个聚合方式
Pandas可视化
-
Pandas可视化是基于Matplotlib的上层封装
-
正常工作一般先用Pandas可视化,再辅以Matplotlib修改组件
-
Pandas可视化的优势:
- 代码简洁
- 针对Pandas数据结构专门优化过(Series/DataFrame)
-
Pandas可视化的劣势:
- Pandas绘图自定义程度较差
- Matplotlib自定义程度高
Series绘图
- matplotlib绘图
- Pandas绘图
- Pandas绘图和Matplotlib绘图代码可以结合使用
DataFrame绘图
- Pandas绘图
Pandas绘图的plot方法的常见参数
和密度估计图比直方图的优势:
- 效能调表现数据分布,可以对比多组数据的分布情况
- 分布情况平滑,更容易观看
柱状图
- 一些常见图表有专有绘图函数,如柱状图 a plot.bar()和plot.barh()分别绘制水平和垂直的柱状图
- Series和DataFrame的索引将会被用作X(bar)或Y(barh)刻度
堆积柱状图
- stacked=True即可为DataFrame生成堆积柱状图,每行的就会堆积在一起
Pandas数据运算 - 自定义函数运算
Python数据科学的基本方式是:向量化运算(矢量化运算),并行运算
如果需要对Pandas数据进行操作或运算(按运算速度排名:)
- 优先使用Pandas库内自带的运算函数,如.sum(), .mean()等
- 如果运算复杂且自带函数无法完成,使用Pandas自定义函数: .apply()
- 注意apply内自定义函数也是用Pandas自带函数,否则见3
- 如果依然难以完成,最后使用Python传统的for循环遍历操作
自定义运算
- apply():Series和DataFrame通过自定义运算函数(计算行/列)
- map():Series用
- applymap():DataFrame用(计算单元格)
针对Series的map函数,会将自定义函数应用到Series对象的每个值
Series的map函数
- 简单运算
# 标量运算:for循环遍历实现
a2 = 0
for i in a:
a2 = a2 + i
a2
sum(a) # 底层实现也是循环遍历
-------------------------
# 向量运算,自带函数
a.sum()
np.sum(a.values)
- 一般复杂运算(Pandas中没有自带方法实现)
#标量运算
a2 = []
for i in a:
a2.append(i + 1 - 2 * 3 / 4)
a2
--------------------------
#向量运算
a + 1 - 2 * 3 / 4
- 对于非常复杂的运算或操作,使用自定义函数的方法实现
- 语法看起来是向量化并行编程,实际上底层运算时遍历循环,类似for循环
#自定义函数
def aaa(x):
return x + 1 - 2 * 3 / 4
a.map(aaa) #Sereis使用map进行自定义函数运算
a.apply(aaa) #Series也能使用apply
-----------------------------
a.apply(lambda x:x + 1 - 2 * 3 / 4) #lambda表达式,乞丐版函数(匿名函数)
DataFrame的自定义函数操作
- apply:操作行、列
- applymap:操作单元格
- 关于行和列的思路
- axis=0 按行操作:给这一列的所有行进行运算
- axis=1 按列操作:给这一行的所有列进行运算
DataFrame的apply自定义函数应用,复杂,重要
Python自带基本统计函数
Pandas的统计运算方法,和Numpy基本一致
默认针对0轴(行)做运算,大部分函数可加参数axis=1 改为对列运算
函数 解释
- .describe():针对0轴的统计汇总,计数/平均值/标准差/最小值/四分位数/最大值
- .sum():计算数据的综合,按0轴计算(各行计算),下同,要按列计算参数1
- .count():非NaN值数量
- .mean() .median() .mode():计算数据的算术平均值/中位数/众数
- .var() .std():计算数据的方差/标准差
- .min() .max():计算数据的最小值/最大值
- .idxmin() .idxmax():计算数据第一最大值/最小值所在的位置的索引,给索引或切片使用(自定义索引,排除null/NA等空值)
b
对Pandas数据结构,不同计算方式的速度比较
- for循环
- 自定义函数.apply()+自带函数
- 自带函数,例如.sum()
- Numpy的ndarray数组自带函数
时间单位:
- 1s = 1000ms
- 1ms = 1000µs
- 1µs = 1000ns
结论:
- 数据量较小的时候,for循环快于其他方式(没用)
- for循环随着数据量变大,运算速度直线下降
- 其他遍历方式各有优势,一般来说,底层数组运算速度最快
离散数据和连续数据:
- 区分方式:
-
如果在两个数据之间可以插入新的数据,数据的应用不会出错,就是连续数据,否则就是离散数据
-
数据去重后的数量,剩下的唯一值和源数据的数量比值是多少(即唯一值相对总之数量多不多)
-
一般性的:如果唯一值太多,就是连续数据,反之是离散数据(多的定义不固定,一般超过30种就算多,可以用直方图理解)
-
特殊的:如果原数据本来就少,看比例,唯一值占比高依然是连续数据
-
总之:如果去重后的数据总量多且占比高,就可以认为是连续数据,反之是离散数据
-
-
为何区分:
不同数据做指标运算的时候是不一样的 -
连续数据:可以运算
- 例如年龄,可以求平均年龄/最大/最小/年龄标准差
- 不能做分组基准(因为太多了)只能做聚合运算
-
离散数据:不可以运算,但可以做计数
- 例如年龄,可以计数每个年龄段多少人(频次)
- 可以做分组基准
数据分析时,为了方便分析,有时需要将连续数据转为离散数据(离散化,面元划分)
(离散数据转连续数据需求较少,因为计算出的指标毫无意义,例如性别计算出平均值0.5,但也有这种情况)
为了便于分析,连续数据常常被离散化或拆分为“面元”,bin(分组区间)
连续数据离散化:连续数据要分析智能化直方图,无法分组聚合,所以可以将这些数据离散化,之后进行分组聚合计算
连续数据离散化(面元划分)
pd.cut()
- 离散值已知,每个区间内元素个数不一致
- 返回的是categories对象(划分的面元),可看做一组表示面元名称的字符串
- 底层含有:
一个codes属性中的年龄数据标签
一个表示不同分类的类型数据
- 底层含有:
pd.qcut()
- 每个区间内元素个数一致,离散区间差值不一致
- 不指定面源切分的其实和结束值,而是指定切分的个数(切成几分),自动计算面元起始结束值
- 按数值间隔等距切分
- 某些数据分布情况cut可能无法使得各个面元含有相同数量的值,qcut使用样本分位数可以得到大小基本相等的面源(按元素个数等量切)
区分:
-
cut是保持区间间隔相同的,每个区间内值个数不同
- 类比直方图,X轴间隔大小一致,Y轴高度不一致
- 优点:根据业务情况自己定义区间和间隔,分析更精确
- 缺点:自定义程度太高,如果去健美分号,分析结果就完全错误
-
qcut是保持每个区间内值个数一直,区间间隔不相同
- 类比直方图,X轴间隔大小不一致,Y轴高度一致
- 优点:自定义性差,不了解业务情况下,分析结果就不会太离谱
- 缺点:自定义程度低,无法根据现实情况修改间隔范围,不会太精确
分位数分析(桶分析)
- 分位数分析(桶分析):不局限于单个数据计算指标,而是用两个或多个数据组合计算多为指标
- 对标进行单列/两列/多列组合分析,叫多维数据分析(其实就是分组聚合/透视表/交叉表操作)
- Pandas有一些能根据指定面元或样本分位数将数据拆分成多块的工具(比如cut和qcut)
- 将这些函数和groupby结合起来,就能实现对数据集的桶(bucket)或分位数(quantile)分析
计算指标/哑变量(了解)
-
为了分析方便,一般把连续数据转为离散数据,便于其作为分组基准
-
有时也需要将离散值转为连续值(可理解为将字符串转为数值),如供机器学习算法
- 简单的转化直接将分类值替换为数值即可,如前期中期后期替换为123
- 复杂的情况需要将分类值转换为哑变量,如各个分类变量没有先后大小关系的时候,如男女
-
一种常用与统计建模或机器学习的转换方式是:将分类变量(categorical variable)转换为哑变量、指标矩阵(虚拟变量,duress(one-hot)编码变量)
-
如果DataFrame的某一列含有k个不同值,则可以派生出一个k列矩阵或DataFrame(其值全为1和0)
-
pandas有一个get_dummies函数可以实现该功能
将不能计算的字符串转为可以计算的数值(表格,或矩阵)
字符串:‘一个对统计应用有用的方法:结合get_dummies和如cut之类的离散化函数’
[统计,应用,有用,方法,结合,离散化,函数]
将人能识别的字符串,转为计算机能计算的值
- 简单方式:性别[男,女] -> [0,1]
- 缺点:转后数值分大小,但原值不分,不精确
- 独特热编码方法:
- [1,1,1,1,1,1,1]
- 列表内有7个词,每个词出现的位置为1,其位置为0
- 统计:[1,0,0,0,0,0,0]
- 方法:[0,0,0,1,0,0,0]
- 词向量
- 一个对统计应用有用的方法:结合get_dummies和如cut之类的离散化函数
离散数据/连续数据指标分析和可视化
连续数据指标计算和可视化
-
对单列的连续数据进行指标计算:
- 指标计算一般是聚合运算
- 可视化一般是看数据分布
-
对单列的连续数据进行可视化:
- 一般是画直方图看分布(本质是将其离散化)
- 散点图,也可以看分布和相关(不如直方图看分布专业)
- 或箱线图,类似四根柱子的直方图
离散数据指标计算和可视化
- 对单列离散数据指标计算:
- 指标计算一般看个书和频次/频率
- 可视化一般就是比较值大小和比例
- 对单列离散数据可视化:
- 条形图:
#条形图 a.gender.value_counts().plot.bar( width = 0.5, #柱子粗细 color='r', alpha = 0.3 ) plt.show()
- 饼图:
#饼图 a.gender.value_counts().plot.pie( figsize=(8,8), #图像大小 explode=(0,0.1), #突出块,突出比例 autopct='%1.1f%%', #显示百分比方式 startangle=90 #饼图起始角度,读属,默认0为右侧水平180度开始,逆时针旋转 ) plt.show()
写一个通用的自动化指标计算和可视化数据分析程序
- 首先判断列的类型(连续/离散)
- 将所有连续列离散化(离散化工作室个性化的,每列根据业务不同区间和面元个数都不同,需要手动设置,也可以自动设置后再调整)
- 使用循环遍历所有列的组合,得出指标和可视化图(一列计算指标/两列组合/三列组合),数学上排列组合
- 人工手动调整结果,最后挑选出符合现时业务情况的指标和图表,写在分析报告上
出指标时同样参照上面的顺序实现
Pandas数据规整 - 转换 - 索引操作
修改Series和DataFrame索引的几种方式:
-
直接赋值修改索引:
- 只能一次赋值修改全部索引,且索引和值对应关系与之前无关(危险操作,最好别用)
-
替换索引值:rename()
- 将于按索引某些替换为新值,不能增加删除
- 保持了索引和值的关系
-
重建整个索引:reindex(),创建一个适应新索引的新对象
- 不替换或修改具体索引值,而是增减索引或改变顺序,与按索引对应的值关系不变(安全操作)
- 它实际上是一种变相的查询方式,类似在查询中加入原数据中没有的新行新列
- loc查询如果索引值不存在,会报警告
- reindex查询如何索引值不存在,会新增一行或一列新值,值为缺失值
-
普通列和索引列互相交换:set_index(), reset_index()
- 将普通列转为行索引:.set_index()
- 行索引转为普通列(删除行索引):reset_index()
Pandas数据规整 - 转换 - 排序和采样
Pandas数据排序
- 给索引排序
- 给值排序
- 给行排序
- 给列排序
- 升序
- 降序
.sort_index()在指定轴上根据索引进行排序,索引排序后内容会跟随排序
随机排列和随机采样
随机排列
利用numpy.random.permutation函数可以实现对Series或DataFrame的列的随机排序工作(permuting,随机重排序)
通过需要排列的轴的长度调用permutation,可产生一个表示新顺序的整数数组:
随机采样
choice(),从一个序列中随机抽取某些值
#按行索引采样
df.index
index = np.random.choice(df.index,size=3,replace=False)
df.loc[index]
------------------
#按行按列随机采样
df.index
df.columns
index = np.random.choice(df.index,size=3,replace=False)
columns = np.random.choice(df.columns,size=2,replace=False)
df.loc[index,columns]
Pandas数据规整 - 清理
对指定数据(如缺失数据、重复数据)进行处理(检查、替换、删除)
- 缺失值的表示:np.nan
- 检查缺失值:isnull(),notnull(),info()
- 删除缺失值:dropna()
- 填充缺失值:fillna()
- 向前填充和向后填充
- 向前填充:使用缺失值的前一个值填充 - method = ‘ffill’
- 向后填充,使用缺失值的后一个值填充 - method = ‘bfill’
- 向前填充和向后填充
- 替换值(填充缺失值是替换值的一种情况,replace方法用作替换值更简单、更灵活):replace()
- 映射数据替换:map除了自定义函数运算,还是一种映射转换元素以及其它数据清理工作的便携方式
- 移除重复数据
#重复行查询:
#布尔型Series,各列重复值交集
data.duplicated()
-------------------
#重复行移除
data[-data.duplicated()]
data.drop_duplicates()
-------------------
#移除自定义重复行
data.drop_duplicates('k1')
-
移除重复索引值
- 带有重复值的轴索引:许多Pandas函数要求标签唯一,但不是强制的
- 索引的is_unique属性判断索引值是否唯一
-
检测和过滤异常值
- 过滤或变换异常值(outlier)在很大程度上就是运用数组运算
使用Pandas缺失值计算
Pandas中,不论缺失值是None还是np.nan,都会被转化为NaN形式
NaN:非数字,not a number,Pandas中他表示缺失或NA值,便于被检测出来本质上就是np.nan
Pandas的对象可以跳过缺失值进行运算4
通过函数检查数据中是否含有缺失值
- 单个空值,底层类型为np.nan,不能直接比较是否相同
- 单个np.nan空值,可以用np.isnan()方法判断是否空值
- Python浮点数计算比较的问题
- 整体判断,表格中各列缺失值情况
isnull()和notnull()
-
适用于单列判断哪些行是缺失值
- isnull():缺失值返回True,正常值返回False
- notnull():正常值返回True,缺失值返回False
-
DataFrame不能通过布尔查询方式过滤缺失值,必须使用Pandas的特定方法过滤
-
查到缺失值后,Series可以直接过滤,DataFrame需要进一步处理(填充或删除)
Pandas数据规整 - 合并
数据合并
Pandas提供了大量方法,能轻松对Series,DataFrame进行合并操作
- 追加:append()
- 连接:concat() #行列均可
- 复杂合并:.merge() 和 .join()
- 按行索引合并:join(),join()是merge()一个特殊用法,用于索引合并,操作简单功能单一
- 按列合并:merge()函数用于复杂综合数据合并,操作复杂功能强大
- 合并重叠数据(一个表为主,先填充再合并):combine_first()
表格合并
两个表必须有相关性,才有合并的需要
以两个表相关的列或行索引为基准合并
方法1:使用查询和添加列进行表合并
(比较麻烦,且行列如不对应容易出现问题)
- 合并两个对象,默认匹配相同过的列名,自动对齐合并
df3 = pd.merge(df1,df2)
------------------------
name group date
0 张三 DBA 2012
1 李四 PM 2004
2 王五 PM 2014
3 赵六 HR 2008
- 要合并的样本量(行数)不一样时,合并后的数据会自动扩展,不损失信息
pd.merge(df3,df4)
------------------------
name group date leader
0 张三 DBA 2012 钱大
1 李四 PM 2004 孙二
2 王五 PM 2014 孙二
3 赵六 HR 2008 周三
- 两个表没有同名列时:
两个对象没有同名列时,用left_on和right_on强制指定列名对应合并
按照行索引合并
- 当要合并数据的行索引相关是,指定merge()函数的参数left_index与right_index的值为True,就可以实现自动依照索引序号合并
- join()函数也能实现,写法更简单
- merge()的优势在于更灵活,尤其是当数据及所引致差别很大,数据合并又必须以其中一组数据的索引值为依据时(一个表用索引,另一个表用普通列做基准)
#方法1:join
df1a.join(df2a)
df1a.join(df2a).reset_index()
#方法2:merge
pd.merge(df1a,df2a,left_index=True,right_index=True) #merge实现,同上
#方法3:表格查询和修改
df2a1 = df2a.copy()
df2a1['group'] = df1a['group']
df2a1.reset_index()
两个对应列不完全重复的数据集的合并
参数how
- how = ‘inner’,交集,两个表共有的行
- how = ‘outer’,并集,两个表所有的行
- how = ‘left’,表1的行
- how = ‘right’,表2的行
合并数据集中包含两个或以上相同列名时
参数on指定用于合并的主键
合并后的数据集中,之前相同的列名会被默认加上_x等后缀用于区分
参数suffixes可以自定义后缀
合并重叠数据(了解)
有一类数据组合问题不能用简单的合并(merge)或链接(concatenation/即concat)运算来处理。如合并全部或部分重叠的两个数据集
距离:使用Numpy的where函数,就表示一种等价于面向数组的if-else
以a为基准合并,a的缺失值使用b填充
方法1:使用原生方式打补丁(a2的缺失值使用b2填充)
#1:使用b2填充a2的缺失值(打补丁)
a2[a2.isnull()] = b2
#2:合并数据
a22 = a2.append(b2)
#3:去重排序
a22.index.duplicated()
a22[~(a22.index.duplicated())].sort_index()
方法2:使用combine_first方法,先打补丁再合并,在去重排序
a2 = a[2:].copy()
b2 = b[2:].copy()
a2.combine_first(b2)