预备知识-python核心用法常用数据分析库(下)

2、预备知识-python核心用法常用数据分析库(下)

概述

Python 是当今世界最热门的编程语言,而它最大的应用领域之一就是数据分析。在python众多数据分析工具中,pandas是python中非常常用的数据分析库,在数据分析,机器学习,深度学习等领域经常被使用。使用 Pandas 我们可以 Excel/CSV/TXT/MySQL 等数据读取,然后进行各种清洗、过滤、透视、聚合分析,也可以直接绘制折线图、饼图等数据分析图表,在功能上它能够实现自动化的对大文件处理,能够实现 Excel 的几乎所有功能并且更加强大。

本实验将通过实战的方式,介绍pandas数据分析库的基本使用,让大家在短时间内快速掌握python的数据分析库pandas的使用,为后续项目编码做知识储备

实验环境

  • Python 3.7
  • Pycharm

任务二:Pandas数据分析实战-1

【任务目标】

本任务主要目标为使用pandas进行数据分析实战,在实战过程中带大家了解pandas模块的一下功能:

  • 了解数据
  • 分析数据问题
  • 清洗数据
  • 整合代码

【任务步骤】

1、准备工作

打开CMD窗口后,执行如下命令,打开jupyter notebook编辑器

jupyter notebook

成功执行以上命令后,系统将自动打开默认浏览器,如下图所示:

预备知识-python核心用法常用数据分析库(下)

成功打开浏览器后,按如下流程创建 notebook 文件

预备知识-python核心用法常用数据分析库(下)

对新建notebook进行重命名操作

预备知识-python核心用法常用数据分析库(下)

预备知识-python核心用法常用数据分析库(下)

2、notebook 文件新建完成后,接下来在新建的 notebook 中编写代码

  • 了解数据

在处理任何数据之前,我们的第一任务是理解数据以及数据是干什么用的。我们尝试去理解数据的列/行、记录、数据格式、语义错误、缺失的条目以及错误的格式,这样我们就可以大概了解数据分析之前要做哪些“清理”工作。

本次我们需要一个 patient_heart_rate.csv 的数据文件,这个数据很小,可以让我们一目了然。这个数据是 csv 格式。数据是描述不同个体在不同时间的心跳情况。数据的列信息包括人的年龄、体重、性别和不同时间的心率。

  • 加载数据即查看数据集
import pandas as pd
df = pd.read_csv('data/patient_heart_rate.csv')
df.head()

运行结果如下:

预备知识-python核心用法常用数据分析库(下)

分析数据问题

  1. 没有列头
  2. 一个列有多个参数
  3. 列数据的单位不统一
  4. 缺失值
  5. 重复数据
  6. ASCII 字符
  7. 有些列头应该是数据,而不应该是列名参数

3、清洗数据

3.1、 没有列头

如果我们拿到的数据像上面的数据一样没有列头,Pandas 在读取 csv 提供了自定义列头的参数。下面我们就通过手动设置列头参数来读取 csv,代码如下:

import pandas as pd
column_names= ['id', 'name', 'age', 'weight','m0006',
                'm0612','m1218','f0006','f0612','f1218']
df = pd.read_csv('data/patient_heart_rate.csv', names = column_names)
df.head()

运行结果如下:

预备知识-python核心用法常用数据分析库(下)

上面的结果展示了我们自定义的列头。我们只是在这次读取 csv 的时候,多了传了一个参数 names = column_names,这个就是告诉 Pandas 使用我们提供的列头。

4、一个列有多个参数

在数据中不难发现,Name 列包含了两个参数 Firtname 和 Lastname。为了达到数据整洁目的,我们决定将 name 列拆分成 Firstname 和 Lastname

使用 str.split(expand=True),将列表拆成新的列,再将原来的 Name 列删除

df[['first_name','last_name']] = df['name'].str.split(expand=True)
df.drop('name', axis=1, inplace=True)
df.head()

运行结果如下:

预备知识-python核心用法常用数据分析库(下)

5、列数据的单位不统一

如果仔细观察数据集可以发现 Weight 列的单位不统一。有的单位是 kgs,有的单位是 lbs

lbs_weight_s = df[df.weight.str.contains("lbs").fillna(False)]['weight']
lbs_weight_s = lbs_weight_s.apply(lambda lbs:  "%.2fkgs" % (float(lbs[:-3])/2.2)  )
df.loc[lbs_weight_s.index,'weight'] = lbs_weight_s

运行结果如下:

预备知识-python核心用法常用数据分析库(下)

6、缺失值处理

在数据集中有些年龄、体重、心率是缺失的。我们又遇到了数据清洗最常见的问题——数据缺失。一般是因为没有收集到这些信息。我们可以咨询行业专家的意见。典型的处理缺失数据的方法:

  • 删:删除数据缺失的记录
  • 赝品:使用合法的初始值替换,数值类型可以使用 0,字符串可以使用空字符串“”
  • 均值:使用当前列的均值
  • 高频:使用当前列出现频率最高的数据
  • 源头优化:如果能够和数据收集团队进行沟通,就共同排查问题,寻找解决方案。

7、重复数据处理

有的时候数据集中会有一些重复的数据,执行以下代码观察数据集前10条数据

df.head(10)

运行结果如下:

预备知识-python核心用法常用数据分析库(下)

观察以上结果,可以发现在我们的数据集中也存在重复的数据,如下

预备知识-python核心用法常用数据分析库(下)

首先我们校验一下是否存在重复记录。如果存在重复记录,就使用 Pandas 提供的 drop_duplicates() 来删除重复数据。

df.drop_duplicates(['first_name','last_name'],inplace=True)
df.head(10)

运行结果如下:

预备知识-python核心用法常用数据分析库(下)

删除weight字段重复的数据

df.drop_duplicates(['weight'],inplace=True)
df.head(10)

运行结果如下

预备知识-python核心用法常用数据分析库(下)

8、 非ASCII 字符

在数据集中 Fristname 和 Lastname 有一些非 ASCII 的字符。

处理非 ASCII 数据方式有多种

  • 删除
  • 替换
  • 仅仅提示一下

我们使用删除的方式:

df['first_name'].replace({r'[^\x00-\x7F]+':''}, regex=True, inplace=True)df['last_name'].replace({r'[^\x00-\x7F]+':''}, regex=True, inplace=True)df.head()

运行结果如下:

预备知识-python核心用法常用数据分析库(下)

9、有些列头应该是数据,而不应该是列名参数

有一些列头是有性别和时间范围组成的,这些数据有可能是在处理收集的过程中进行了行列转换,或者收集器的固定命名规则。这些值应该被分解为性别(m,f),小时单位的时间范围(00-06,06-12,12-18)

sorted_columns = ['id','age','weight','first_name','last_name']df = pd.melt(df,             id_vars=sorted_columns,             var_name='sex_hour',             value_name='puls_rate')df = df[df.puls_rate != '-'].dropna()df = df.sort_values(['id','first_name','last_name']).reset_index()def split_sex_date(sex_hour):    sex = sex_hour[:1]    if 'f' == sex:        sex = '女'    elif 'm' == sex:        sex = '男'    hour = sex_hour[1:]    return pd.Series([sex,hour])df[['sex','hour']] = df.sex_hour.apply(split_sex_date)df.drop('sex_hour',axis=1)

运行结果如下:

预备知识-python核心用法常用数据分析库(下)

任务三:Pandas数据分析实战-2

【任务目标】

本任务主要目标为使用pandas进行数据分析实战,在实战过程中带大家了解pandas模块的一下功能:

  • 日期的处理
  • 字符编码的问题

【任务步骤】

1、参考【任务一】第1步中操作,在jupyter notebook编辑中重新新建一个notebook 文件,命名为 pandas-data-processing-3,如下图所示:

预备知识-python核心用法常用数据分析库(下)

2、预览数据

这次我们使用 Artworks.csv,我们选取 100 行数据来完成本次内容。具体步骤:

  • 导入Pandas
  • 读取 csv 数据到 DataFrame(要确保数据已经下载到指定路径)

DataFrame 是 Pandas 内置的数据展示的结构,展示速度很快,通过 DataFrame 我们就可以快速的预览和分析数据。代码如下:

import pandas as pddf = pd.read_csv('./data/Artworks.csv').head(100)df.head(10)

运行结果如下:

预备知识-python核心用法常用数据分析库(下)

2、统计日期数据

我们仔细观察一下 Date 列的数据,有一些数据是年的范围(1976-1977),而不是单独的一个年份。在我们使用年份数据画图时,就不能像单独的年份那样轻易的画出来。我们现在就使用 Pandas 的 value_counts() 来统计一下每种数据的数量。

首先,选择要统计的列,并调用 value_counts():

df['Date'].value_counts()

运行结果如下:

预备知识-python核心用法常用数据分析库(下)

3、日期数据问题

Date 列数据,除了年份是范围外,还有三种非正常格式。下面我们将这几种列出来:

  • 问题一,时间范围(1976-77)
  • 问题二,估计(c. 1917,1917 年前后)
  • 问题三,缺失数据(Unknown)
  • 问题四,无意义数据(n.d.)

接下来我们会处理上面的每一个问题,使用 Pandas 将这些不规则的数据转换为统一格式的数据。

问题一和二是有数据的只是格式上欠妥当,问题三和四实际上不是有效数据。针对前两个问题,我们可以通过代码将据格式化来达到清洗的目的,然而,后两个问题,代码上只能将其作为缺失值来处理。简单起见,我们将问题三和四的数据处理为0。

处理问题一

问题一的数据都是两个年时间范围,我们选择其中的一个年份作为清洗之后的数据。为了简单起见,我们就使用开始的时间来替换这样问题的数据,因为这个时间是一个四位数的数字,如果要使用结束的年份,我们还要补齐前两位的数字。

首先,我们需要找到问题一的数据,这样我们才能将其更新。要保证其他的数据不被更新,因为其他的数据有可能是已经格式化好的,也有可能是我们下面要处理的。

我们要处理的时间范围的数据,其中包含有“-”,这样我们就可以通过这个特殊的字符串来过滤我们要处理的数据,然后,通过 split() 利用“-”将数据分割,将结果的第一部分作为处理的最终结果。

代码如下

row_with_dashes = df['Date'].str.contains('-').fillna(False)for i, dash in df[row_with_dashes].iterrows():    df.at[i,'Date'] = dash['Date'][0:4]df['Date'].value_counts()

运行结果如下:

预备知识-python核心用法常用数据分析库(下)

处理问题二

问题二的数据体现了数据本身的不准确性,是一个估计的年份时间,我们将其转换为年份,那么,就只要保留最后四位数字即可,该数据的特点就是数据包含“c”,这样我们就可以通过这一特征将需要转换的数据过滤出来。

row_with_cs = df['Date'].str.contains('c').fillna(False)for i,row in df[row_with_cs].iterrows():    df.at[i,'Date'] = row['Date'][-4:]df[row_with_cs]

运行结果如下:

预备知识-python核心用法常用数据分析库(下)

处理问题三四

将这问题三四的数据赋值成初始值 0

df['Date'] = df['Date'].replace('Unknown','0',regex=True)
df['Date'] = df['Date'].replace('n.d.','0',regex=True)
df['Date']

运行结果如下:

预备知识-python核心用法常用数据分析库(下)

4、附:完成代码

注意:完整代码中删除了数据展示部分

import pandas as pd
df = pd.read_csv('../data/Artworks.csv').head(100)
df.head(10)
df['Date'].value_counts()
row_with_dashes = df['Date'].str.contains('-').fillna(False)
for i, dash in df[row_with_dashes].iterrows():
    df.at[i,'Date'] = dash['Date'][0:4]
df['Date'].value_counts()
row_with_cs = df['Date'].str.contains('c').fillna(False)
for i,row in df[row_with_cs].iterrows():
    df.at[i,'Date'] = row['Date'][-4:]
df['Date'].value_counts()
df['Date'] = df['Date'].replace('Unknown','0',regex=True)
df['Date'] = df['Date'].replace('n.d.','0',regex=True)
df['Date'].value_counts()
上一篇:WEBAPI POST 传递多个参数时使用dynamic


下一篇:05类与对象1_封装