29期第十二周笔记

Week 12

本周学习主要内容为Pandas剩余部分(自定义函数运算,分组聚合进阶,可视化,数据规整)、重塑和轴向旋转、透视表和交叉表、离散化

数据分析流程

软件开发流程:

  • 需求分析
  • 设计
  • 编码
  • 测试

数据分析流程:

  • 基本流程
  1. 提出问题
  2. 准备数据 (1,2步现实中可能顺序颠倒)
  3. 分析数据
  4. 洞察结论
  • 不断迭代

  • 拓展流程

    1. 需求层:目标确定
    2. 数据层:
      • 数据获取
      • 数据规整(预处理,清洗)
        - 清理 / 转换 / 合并 / 重塑
        - 数据重构,特征工程
    3. 分析层:
      • 描述性分析(对现有数据的理解更加深入)
        > 构建指标(分组聚合旋转 / 透视表 / 交叉表)
        > 数据可视化
      • 探索性分析(可选,挖掘数据之下的信息,或预测未知数据)
        > 建模分析
        > 模型验证
        > 迭代优化
    4. 输出层:
      • 洞察结论,结果可视化,报告撰写,成果应用(宣讲,推动)
  • 优化迭代


数据分析师日常工作:

业务性数据分析师

  • 报表处理(数据规整)
  • 指标计算
  • 可视化
  • 建模预测

综合:数据分析报告

数据分析报告书写套路

  1. 背景介绍
    - 情况介绍(公司情况、接单情况)
    - 数据介绍
    - 需求(分析什么)
  2. 数据工程:
    - 数据获取:SQL、爬虫、买……
    - 数据预处理:载入清洗,重构
  3. 数据分析
    - 描述性分析:
    > 指标计算(分组聚合旋转、透视表、交叉表)(反复迭代)
    > 数据可视化(反复迭代)
    - 探索性分析(建模预测),可选
  4. 结论
    - 总结分析结果
    - 意见建议

透视表(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数据进行操作或运算(按运算速度排名:)

  1. 优先使用Pandas库内自带的运算函数,如.sum(), .mean()等
  2. 如果运算复杂且自带函数无法完成,使用Pandas自定义函数: .apply()
    • 注意apply内自定义函数也是用Pandas自带函数,否则见3
  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)

你可能感兴趣的:(python)