基于Pandas的数据处理与分析方法总结

  1. 基于Pandas的数据处理与分析方法总结

    1. 使用Pandas进行数据处理概述

      1. 数据处理目标

      2. 理解“脏数据”

      3. 理解“干净的数据”

      4. 理解Pandas的数据类型

        1. Series
        2. DataFrame
      5. 数据处理与分析流程叙述

    2. 数据处理过程

      1. 读取数据

      2. 查看数据信息

        1. 查看表的行数和列数
        2. 查看表的表头
        3. 查看表格的前几行
        4. 查看表格的后几行
        5. 查看表格数据摘要
        6. 查看表格数值变量的描述性统计结果
        7. 使用pandas_profiling生成数据集信息报告
      3. 数据处理方法

        1. 使用Pandas操纵数据方法

          1. 基于列的操作
          2. 基于行的操作
      4. 实际频繁遇到的问题

      5. 实际问题解决方案

本文的目的是记录和总结,我本人使用Pandas做数据处理与分析一年半以后的经历体会。其中大部分内容是数据处理的相关内容,还有一小部分是关于分析的内容,主要是描述性统计。另外,本文不涉及机器学习和一些常见的统计的方法内容(回归分析、推断统计等)。

使用Pandas进行数据处理概述

数据处理目标

数据处理的目标,简而言之就是把“脏数据”,尽过一些处理转换,把数据整理成利于分析和建模的“干净的数据”。

理解“脏数据”

对于脏数据没有明确的定义,可以从一下几点理解。

  1. 列变量设置不合理,不利于使用Pandas完成相关的数据分析需求。
  2. 表格数据值不规范,不清晰。
  3. 可能存在异常数据(空值、重复值、不合理值)。

理解“干净的数据”

干净的数据应该符合一下要求:

  1. 每个单元格只储存单一信息
  2. 每列是不同的变量
  3. 每行是不同的观测值
  4. 每个特定观测目的组成一张表

理解Pandas的数据类型

Series

Series是一种带有标签的一维数组,数组可以存放任意类型的数据,数组对应的标签被称为索引(Index),索引和数组对应的值一一对应。

series

Series特性:

  1. name属性 默认为空,可以赋值,当Series转换为dataframe的时候可以用做列名

  2. 具备字典一样的属性和方法 Series的index和value类似于字典的key和value,可以用处理字典的方式处理Series。

  3. 使用行索引轻松选择Series的元素 根据索引可以快速访问Series的子集或者单一元素。

  4. 使用整数索引方式也可也轻松访问Series的元素 Series的值的部分是一个numpy一维数组,所以可以使用类似于numpy风格的方式选择数据

DataFrame

DataFrame是一种带有行和列标记的表格型数据结构,行标记被称作index(索引),列标记被称作column(列名),值的部分是一个二维数组。

dataframe

DataFrame特性:

  1. index

    dataframe的行索引,数组类型的数据,用于行方向的选择、访问、操控DataFrame。

  2. Column

    dataframe的列索引,数组类型的数据,通常被称作列名,用于列方向的选择、访问、操控Dataframe。

  3. value

    dataframe的值的部分是一个二维数组,通常一列值的数据类型应该是一致的,一行值表达的是一个样本的各种特征的记录。

  4. dtype

    dataframe的所有列都有特定的数据类型,这个数据类型确定了每列的值应该是什么数据类型。

  5. series

    当选择df其中一列,构造出来的结果就是前面所提到的series数据类型,列名即series的name属性,df的行索引即是series的索引。

数据处理与分析流程叙述

  1. 根据不同的数据源读取数据到DataFrame(以下简写为df1

  2. 观测df行列结构与值内容,思考数据哪些方面不符合干净数据的要求。

  3. 根据观察和业务需要,编写数据处理脚本,生成干净的数据。

  4. 如果需要进行数据分析,可以从这份干净的数据开始,编写符合分析需求的脚本,包括不限于一下内容:

    1. 对某些变量做有实际意义的四则运算或者描述性统计[平均值、最大值、最小值、中位数、众数、分位数、方差、峰度、偏度]
    2. 根据特定分类变量分组,然后对每组特定变量做筛选、排序、聚合、映射操作。
    3. 根据某些业务需求,改变数据的呈现方式,让数据阅读者更易提炼出价值。
    4. 透视表操作。
  5. 将清洗的数据导出到特定储存载体(如excel文件、csv文件、数据库)。

数据处理过程

读取数据

读取各种数据源,比如(CSV、SQL、Excel、JSON、txt等),然后转换为 dataframe

table_01:

 姓名语文数学英语考试类型
0吕傲文575966期中
1张香秀789066期中
2麻寒636070期中
3廉凡617191期中
4冯乐萱769687期中
5吕傲文658177期末
6张香秀909479期末
7麻寒969767期末
8廉凡597063期末
9冯乐萱607671期末

需要注意的问题:

查看数据信息

查看表的行数和列数

查看表的表头

查看表格的前几行

 姓名语文数学英语考试类型
0吕傲文575966期中
1张香秀789066期中
2麻寒636070期中

查看表格的后几行

 姓名语文数学英语考试类型
7麻寒969767期末
8廉凡597063期末
9冯乐萱607671期末

查看表格数据摘要

查看表格数值变量的描述性统计结果

 语文数学英语
count101010
mean70.579.473.7
std13.818314.43919.51081
min575963
25%60.2570.2566.25
50%6478.570.5
75%77.59378.5
max969791

使用pandas_profiling生成数据集信息报告

使用pandas_profiling可以自动生成关于df的各种角度的详细的关于数据的元信息报告,对于简单的数据其实没有必要使用这个工具,但是它对于快速观测数据源的信息的确非常有用。

输出结果见此链接: pandas_profiling_output

数据处理方法

数据处理方法没有固定的流程和套路,具体使用什么方法处理数据,需要根据具体数据和实际需求来针对性处理。但是数据处理方法还是有迹可循的,下面是使用Pandas常用的必然遇到的数据操纵方法总结

使用Pandas操纵数据方法

说明:

基于列的操作
  1. 重命名列名

  2. 重排序列名

  3. 选择列

    详解df.select_columns

    1. 选择列名支持通配符

      当你需要选择多列的时候,然后多列的名称又遵循某个规则,使用通配符选择列名的方法会比传递一个实际列名数组要快速、简洁很多。

      Table_02:

       排名球队场次积分进球失球净胜球
      01埃弗顿5134101477
      12阿斯顿维拉5124011257
      23利兹联6103121293
      34利物浦51031113130
      45莱斯特城593021284
      56阿森纳59302862
      67狼队5930257-2
      78热刺582211587

      需求:Table_02是截止于北京时间2020年10月24日的英超积分榜前8名数据,如何只选择排名、球队、进球、失球和净胜球五列呢?

      Pandas原生方法:

      使用通配符方法是这样:

      输出结果:

       排名球队进球失球净胜球
      01埃弗顿1477
      12阿斯顿维拉1257
      23利兹联1293
      34利物浦13130
      45莱斯特城1284
      56阿森纳862
      67狼队57-2
      78热刺1587

      两种方法对比显然第2种方法更加简洁,同时减少编码时间。

    2. 支持反向选择

      该方法可以支持反向选择列,如果你只是需要从源数据里排除很少的列不选择,反向选择是一个比较便利的方式。

      需求:如何选择除了场次之外的所有列

      Pandas原生方法:

      反向选择方法:

      输出结果:

       排名球队积分进球失球净胜球
      01埃弗顿134101477
      12阿斯顿维拉124011257
      23利兹联103121293
      34利物浦1031113130
      45莱斯特城93021284
      56阿森纳9302862
      67狼队930257-2
      78热刺82211587

      显而易见,select_columns方法更加方便使用!

  4. 移除列

  5. 增加列

  6. 增加多列

    详解df.add_columns:

    需求: 继续以Table_02为例,新增加两列计算不败率和场均失球

    Pandas原生方法(额外扩展2种方法):

    df.add_columns方法:

    输出结果:

     排名球队场次积分进球失球净胜球不败率场均失球
    01埃弗顿513410147711.4
    12阿斯顿维拉51240112570.81
    23利兹联61031212930.6666671.5
    34利物浦510311131300.82.6
    45莱斯特城5930212840.61.6
    56阿森纳593028620.61.2
    67狼队5930257-20.61.4
    78热刺5822115870.81.6

    add_columns方法的优点是比常规方法简洁,比高级用法语义明确。

  7. 拆分单列

  8. 合并多列

基于行的操作
  1. 选择行

    1. 选择特定行
    2. 选择重复行
    3. 筛选行
  2. 删除行

    1. 删除特定行
    2. 删除空值行
    3. 删除重复行
  3. 增加行

实际频繁遇到的问题

  1. 观察是否存在列名命名不规范

    如果存在列名命名不规范,修改列名。 列名的命名要求是在保证语义明确的前提下尽可能简洁,避免使用各种标点符号。(Table_01命名没有不规范不需要修改)

  2. 是否存在一个变量被存储于多列

    可以使用melt操作将多列融化到单列,然后再标记多列对应的分类变量类型值。

     姓名考试类型科目成绩
    0吕傲文期中语文86
    1吕傲文期中数学90
    2吕傲文期中英语91
    3张香秀期中语文67
    4张香秀期中数学79
    5张香秀期中英语78
    6麻寒期中语文73
    7麻寒期中数学57
    8麻寒期中英语85
    9廉凡期中语文96
    10廉凡期中数学65
    11廉凡期中英语68
    12冯乐萱期中语文73
    13冯乐萱期中数学56
    14冯乐萱期中英语76
    15吕傲文期末语文90
    16吕傲文期末数学67
    17吕傲文期末英语76
    18张香秀期末语文89
    19张香秀期末数学96
    20张香秀期末英语100
    21麻寒期末语文76
    22麻寒期末数学67
    23麻寒期末英语94
    24廉凡期末语文84
    25廉凡期末数学62
    26廉凡期末英语83
    27冯乐萱期末语文65
    28冯乐萱期末数学75
    29冯乐萱期末英语56
  3. 是否存在一列存储了多个变量

    可以使用字符串分列或者正则表达式提取的方法拆分至多列。

  4. 是否存在多个变量,有的存储在行,也有的储存在了列

    先进行melt然后再进行unstack

     姓名科目期中期末
    0冯乐萱数学8481
    1冯乐萱英语58100
    2冯乐萱语文8384
    3吕傲文数学6761
    4吕傲文英语8867
    5吕傲文语文6777
    6廉凡数学5896
    7廉凡英语9063
    8廉凡语文9979
    9张香秀数学5891
    10张香秀英语9281
    11张香秀语文7796
    12麻寒数学5559
    13麻寒英语8181
    14麻寒语文8497
  5. 是否存在不同观测目的的表被组合在一张表内

    根据表的定义分解到多表中,方法通常是选择需要的列,删除重复的行,保存ID列,拆分到多张表。

  6. 是否存在同一观测目的的数据被储存在了多个表中

    循环读取每张表然后合并到一张表

  7. 是否存在完全无意义的空行和空列

    删除无意义的空行或者空列

  8. 是否定义准确数据类型

    如果数据类型可能存在问题,可以转换到需要的数据类型。

  9. 是否需要进行多表联接,是否可以多表连接,使用哪种联接方式

    如果需要多表联接,首先需要找到匹配的ID列,匹配的ID列可以是多列组合也可以单独的ID列。 根据具体需求,可以采用内联接,左联接,外联接。

  10. 是否存在重复的数据行

    如果存在完全重复的数据行,需要删除。

实际问题解决方案

根据具体数据处理需求的不同,会需要采取不同的操作,但是绝大部分不外乎以下内容。


1 文中“df”与“表格”二者指的都是一个意思,就是读到Pandas里面的表格类型的数据源
2 pyjanitor是基于Pandas生态建立的数据处理工具包,它为数据处理提供了一套干净、易用、规范和强大的api