python数据分析

利用python数据分析

1.安装anaconda——编程工具的选择

IPython:交互式的编程工具,用户编写完代码后,按Enter键即可运行程序,是便于测试代码或快速运行小型代码;弊端是无法保存编辑的代码块。
Jupyter Notbook:使用时会激活计算机中的浏览器,代码的编写和运行都在浏览器中完成
Spyder:更像一个软件,在自己的工作界面中运行。
本文选择Jupyter作为python代码的编译环境,主要是因为七操作界面具有简洁性和扁平化特征,并且Jupyter编写Python代码更像是写笔记的过程,非常简单且可以实现自动保存。

2.Jupyter使用技巧

(1)代码运行组合键
代码运行:Ctrl+Enter或者Shift+Enter完成代码的运行
前者仅执行当前代码框中的代码,后者在执行完成当前代码框中的代码会进入到下一个代码框内或信件代码框

(2)代码框的操作组合键
在代码的编辑过程中,可能会碰到代码框相关的处理,如增加或删除代码框,只需要进入命令状态(按ESC键),再按入A、B或X字母即可(不分大小写)。A表示在当前代码框的前面增加代码框,B表示在当前代码框的后面新增代码框;X表示删除当前的代码框
(3)注释组合键
Ctrl+/:给代码行或代码块增加注释功能
(4)帮助组合键
Shift+Tab(一次Tab):返回简洁版的帮助文档(仅包含函数的参数名称和说明)
Shift+Tab(两次或三次次Tab):返回详细的帮助文档(包含参数的具体含义以及使用方法)
Shift+Tab(四次Tab):重新弹出帮助文档的窗口,文档内同样包含函数的详细信息
(5)代码与笔记的切换组合键
ESC+M:切换时笔记框环境(不要忘了按Enter激活Markdown编辑)

3.数据读取——从pandas开始

(1)文本文件的读取

对于csv或txt后缀的文本文件,可以使用pandas模块中的read_table函数或者read_csv函数,他们的功能完全相同,所不同的是,各自函数中sep参数(即用于指定变量之间的分隔符)的默认值不同。
read_table 函数的使用方法和重要参数如下:

read_table(filepath_or_buffer,#指定TXT文件或CSV文件所在的具体路径,除此之外还可以指定存储数据的网站链接
           sep='\t',#指定元数据集中各变量之间的分隔符,默认为tab制表符
           header='infer'#是否需要将元数据集中的第一行作为表头,默认是需要的,并将第一行用作变量名称;如果原始数据中没有表头,则改参数需要设置None
           names=None,#如果原数据集中没有变量名称,可以通过该参数在数据读取时给数据框添加具体的变量名称
           index_col=None,#制定原数据集中的某些列作为数据框的行索引(标签)
           usecols=None,#制定需要读取原数据集中的哪些变量名
           dtype=None,#读取数据时,可以为原数据集的每个变量设置不同的数据类型
           converters=None,#通过字典格式,为数据集中的某些变量设置和转换函数
           skiprows=None,#数据读取时,指定需要调过原始数据集的起始行数
           skipfooter=None,#数据读取时,指定需要跳过元数据记得末尾行数
           nrows=None,#指定数据读取的行数
           na_values=None,#指定原数据集中哪些特征的值作为缺失值(默认将两个分隔符之间的空值视为缺失值)
           skip_blank_lines=True,#读取数据是是否需要跳过原数据集中的空白行,默认为TRUE
           parse_datas=False,#如果参数值为True,则尝试解析数据框的行索引;如果参数为列表,则尝试解析对应的日期列;
                             #如果参数为嵌套列表,则将某些列合并为日期列;如果参数为字典,则解析对应的列(即字典中的值),并生成新的变量名(即字典中的键)
           thousands=None,#制定原始数据集中的千分位符
           comment=None,#制定注释符,在读取数据时,如果碰到行首制定的注释符,则跳过该行
           encoding=None)#为防止中文的乱码,可以借助该参数解决问题(通常设定为“utf-8”或"gbk")

示例:
读入下面的有效数据:
在这里插入图片描述

#导入第三方模块
import pandas as pd
data1=pd.read_table(
        filepath_or_buffer=r'E:\第5章\datas\data1.txt',#制定文件路径
        sep=',',#指定分隔符
        header=None,#不需要将原书数据中的第一行读作表头
        names=['id','name','gender','occupation'],#重新维格列齐变量名称
        skiprows=2,#跳过起始的两行数据
        skipfooter=2,#跳过末尾的两行数据
        comment='#',#不读取“#”开头的数据
        converters={'id':str})#对工号变量进行类型转换,避免开头的00消失
data1

结果:
在这里插入图片描述

(2)电子表格的读取

另一类常见的数据是xls或xlsx后缀的Excel电子表格数据,该数据的读取可以使用read_excel函数,相关用法及参数如下:

#读入Excel文件
read_excel(
            io,#指定电子表格的具体路径
            sheetname=0,#指定需要读取电子表格中的第几个sheet,可以传递整数也可以传递具体的sheet名称
            header=0,#同上
            skiprows=None,#同上
            skip_footer=0,#同上
            index_col=None,
            names=None,
            parse_cols=None,
            parse_datas=False,#该参数在函数内不在生效
            na_values=None,
            thousands=None,
            converter_float=True#通过字典形式,制定那些列表需要转换成什么形式)
           
           

示例:
读入下列表格中有效内容:
在这里插入图片描述

data2=pd.read_excel(
    io=r'E:\第5章\datas\data2.xlsx',
    header=None,
    names=['id','date','prod_name','color','price'],
    na_values='未知',
    converters={0:str})
data2

在这里插入图片描述

(3)数据库中的数据的读取

在实际工作中,数据通常是存储在数据库中,读入SQL Server数据库的数据要使用pymssql,读入MySQL数据库的数据需要使用Pymysql模块;
SQL server导入模块:在Jupyter中输入“!pip install pymssql”
MySQL导入模块:在Jupyter中输入“! pip install pymysql”
然后基于两个模块各自的connect函数构建数据库与python之间的桥梁,最后在搭建好连接的基础上,使用pandas模块中的read_sql函数实现数据库数据的读取。
(1)关于两个模块中connect函数的用法及参数含义如下:
1)pymssql.connect函数

pymssql.connect(server=None,#指定需要访问的SQL Server服务器,如果是本地数据库,则指定“localhost”;如果是远程服务器,则指定具体的IP地址
                user=None,#指定访问SQL Server数据库的用户名
                password=None,#指定访问SQL Server数据库的密码
                database=None,#指定访问SQL Server数据库的具体库名
                charset=None)#指定读取SQL Server数据库的字符集,(主要是为了防止乱码),如果数据库表中含有中文,一般那可以尝试将该参数
                             #设置为"utf-8"或“gbk”  
2)pymysql.connect函数
pymysql.connect(host=None,#指定需要访问的SQL Server服务器,如果是本地数据库,则指定“localhost”;如果是远程服务器,则指定具体的IP地址
                user=None,#指定访问SQL Server数据库的用户名
                password=''e,#指定访问SQL Server数据库的密码
                database=None,#指定访问SQL Server数据库的具体库名
                port=0,#指定访问MySQL数据库的端口号
                charset='')#指定读取SQL Server数据库的字符集,(主要是为了防止乱码),如果数据库表中含有中文,一般那可以尝试将该参数
                             #设置为"utf-8"或“gbk”

(2)read函数

# read函数:
pd.read_sql(
    sql,#指定一段字符型的SQL查询代码,用于说明数据的读取逻辑
    con,#自动数据库与python之间的连接桥梁
    index_col=None,#指定哪些字段用作数据库的行索引
    coerce_float=True,#bool类型的值,用于判断是否将字符的变量强制转换为浮点型,默认为True
    parse_dates=None,#指定哪些字段需要做日期类型的转换
    columns=None) #指定数据中的哪些字段需要读入到python环境中

示例:使用MySQL中的trin库中的sec_building表

! pip install pymysql#安装连接数据库的包

在这里插入图片描述

#导入第三方模块
import pymysql
#连接SQL Server数据库
conn=pymysql.connect(
    host='localhost',
    user='root',
    password='9710',
    database='trin',
    port=3306,
    charset='utf8'
)
#读取数据
user=pd.read_sql(
    'select * from sec_buildings ',conn
)
#关闭连接
conn.close()
# 数据输出
user

结果:
在这里插入图片描述

4.常见的数据处理技术

(1)数据的概览与清洗

(1)数据类型的判断和转换

如图为某公司的个人信息和交易数据,导入到python中:
在这里插入图片描述

data3=pd.read_excel(io=r'E:\第5章\datas\data3.xlsx')
# data3

#查看数据的规模
data3.shape
#查看表中各变量的数据类型
data3.dtypes

查看原始数据:
在这里插入图片描述
查看数据规模:
在这里插入图片描述
查看数据类型
在这里插入图片描述

除id和age变量为数值型,其余变量均为字符型,直观上能感受到数据类型不对;消费金额custom_amt应该为数值型,订单日期应该为日期型;
接下来需要对这些数据类型进行处理:

#数值型转字符型
data3['id']=data3['id'].astype(str)
#字符型转数值型
data3['custom_amt']=data3['custom_amt'].str[1:].astype(float)
#字符型转日期型
data3['order_date']=pd.to_datetime(data3['order_date'],format='%Y年%m月%d日')

data3.dtypes

修改结果:
在这里插入图片描述
如果某一步代码写错了,但是其他的执行成功,比如说,我的第一个字符修改失败,但是后面两个修改成功了,那么在此运行此代码会显示错误,所以再改的时候最好是一次改一个叭
在这里插入图片描述
3个变量全都转换成了各自所期望的数据类型;
astype方法用于数据类型的强制转换,可选择的常用转换类型包括str(字符型),float(浮点型)和int(整型);
由于custom_amt百年两种的值包含人民币符号¥,所以在数据类型转换之前必须将其删除,(通过字符串切片方法删除,[1:]表示从字符串的第二个元素开始截断)
对于字符和日期问题,推荐更灵活的to_datetime函数,因为他在format参数的调解下,可以识别任意格式的字符型日期值。
需要注意的是,python中的函数有两种表现形式:
①常规理解下的函数,语法为:func(parameters),如to_datetime函数
②另一种则是“方法”,语法为:obj.func(parameters)
二者的区别在于,方法是针对特定的对象的函数,即该方法只能用在某个固定类型的对象上,而函数并没有这方面的限制。

基于上述类型转换的结果,最后再查看一下清洗后的数据:
在这里插入图片描述

(2)冗余数据的判断和处理

冗余的重复观测值(指数据行重复出现)和缺失值等。
可以通过duplicated方法进行“脏”数据的识别和处理。仍对上述data3数据集为例进行操作。

#判断数据中是否存在重复观测值
data3.duplicated().any()

在这里插入图片描述结果返回false,说明该数据集中并不存在重复观测值,如果出现了重复的观测值,可以使用drop_duplicated方法将冗余信息删除。

(3)缺失数据的判断和处理

判断一个数据集是否存在缺失观测值,通常从两方面入手:
①从变量的角度:即判断每个变量中是否包含缺失值
②从数据行的角度:即判断每行数据中是否包含缺失值
关于缺失值可以使用isnull方法,使用isnull方法对data3数据集缺失值进行判断

①从变量的角度来看:

#判断各变量中是否存在缺失值
data3.isnull().any(axis=0)

在这里插入图片描述

#各变量中缺失值的数量
data3.isnull().sum(axis=0)

在这里插入图片描述

#各变量中缺失值的数量
data3.isnull().sum(axis=0)
#各变量中缺失值的比例
data3.isnull().sum(axis=0)/data3.shape[0]

在这里插入图片描述
结果显示,数据集data3中有3个变量存在缺失,即gender,age,edu,他们缺失的数量分别为136,100,1927,确实是比例分别为4.53%,3.33%,64.23%

②从数据行来看

#判断个数据行是否存在缺失值
data3.isnull().any(axis=1).any()

在这里插入图片描述

结果返回TRUE,说明data3中的数据航存在缺失值,上述代码使用了两次any方法,第一次用于判断每一行是否存在缺失值,第二次则综合判断所有行中是否包含缺失值

#判断缺失值的行数
data3.isnull().any(axis=1).sum()

在这里插入图片描述

进一步查看缺失值的行数,为2024行

#判断缺失值的比例
data3.isnull().any(axis=1).sum()/data3.shape[0]

在这里插入图片描述
行缺失比例达到了67.47%

(4)缺失值的处理办法

①删除法:将缺失值所在的观测行删除,前提是确实行的比例非常低,如5%
②替换法:直接利用缺失变量的均值、中位数、或众数替换该变量中的缺失值,好处是:处理速度快,弊端是易产生有偏估计,导致缺失值的准确性下降
③插补法:利用有监督的机器学习方法(如回归模型,树模型,网络模型等)对缺失值做预测,优势在于预测的准确性高,缺点是需要大量的计算,导致缺失值的处理速度大打折扣。

示例:
①删除法

#删除变量,如删除缺失值非常高的edu变量
data3.drop(labels='edu',axis=1,inplace=True)
#数据预览
data3.head()

labels参数用于指定需要删除的变量的名称,如果是多个变量,则需要将这些变量名称写在一对中括号中[‘var1’,‘var2’,‘var3’];删除变量一定要设置axis参数为1,因为变量个数发生了变化;inplace表示时候原地修改,即是否直接将原表中的变量进行删除;若设置为false,则会先输出删除变量的预览效果,而非真正改变原始数据。

#删除观测值,如删除age变量中对应的确实观测值
data3_new=data3.drop(labels=data3.index[data3['age'].isnull()],axis = 0)
#查看数据的规模
data3_new.shape

在这里插入图片描述

利用drop方法实现了数据行的删除,但必须将axis的参数设置为0,此时labels的参数则需要指定待删除的行编号。
(因为是连续做的代码,所以按行删除中,edu的字段是没有的,如果重新再导入一遍数据,在执行此代码是有edu字段的)
如果变量的缺失比例非常大,或者缺失行的比例非常小时,使用删除法是一个不错的选择

②替换法

#替换法处理缺失值
data3.fillna(value={'gender':data3['gender'].mode()[0],#使用性别的众数替换缺失性别
                    'age':data3['age'].mean()#使用年龄的平均值替换缺失年龄
                    },
            inplace=True#原地修改数据
            )
#查看各变量的缺失比例
data3.isnull().sum(axis=0)                      

在查看各变量的缺失比例在这里插入图片描述
结果显示,采用替换法后,原始数据中的变量不再含有缺失值(除了edu,大该变量大量缺失,可删除处理)。缺失值的填充使用fillna方法,其中value参数可以通过字典的形式对不同的变量指定不同的值。需要说明的是,如果计算某个变量的众数,一定要使用索引技术,例如代码中的【0】,表示取出众数序列中的第一个(假设一个变量中有多个众数,那么python将会把这些值以序列的形式存储起来,故取出指定的众数必须使用索引)

③插补法
虽然替换法简单高效,但是其替换的值往往不具有很高的准确性,于是出现了插补法。由于该方法涉及到了机器学习,后续在补充。

(2)数据的引用

数据引用是指如何基于已有的数据内容进行指定目标的筛选。例如仅对某两个月的数据做对比分析;对某种支付方式的用户做特征分析。可以使用iloc,loc,ix方法方便地实现数据挑选,语法相同,如下:
iloc:只能通过行号和列号进行数据的筛选,即只能向[rows_select,cols_select]指定整数列表。第一行第一列必须用0表示;既可以向rows_select或cols_select指定连续的整数编号(即切片用法,语法为:start🔚step,期中step默认为1,结束为止end是取不到的),也可以指定间断的整数编号;‘i’可以认为是“integer”的首字母
loc:比iloc灵活一些,可以向[rows_select,cols_select]指定具体的行标签(行名称)和列标签(列名称),这里是标签而不再是整数索引。‘l’可以认为是“label”的首字母
ix:是iloc和loc的混合,该方法吸收了iloc和loc的优点----------
版本升级导致,在pandas的1.0.0版本开始,移除了Series.ix and DataFrame.ix 方法
使用DataFrame的loc方法或者iloc方法进行替换!----------------

示例:

#构造数据框
df1=pd.DataFrame({'name':['甲','乙','丙','丁','戊'],
                  'gender':['男','女','女','女','男'],
                  'edu':['本科','本科','硕士','本科','硕士'],
                  'age':[23,26,22,25,27]},
                 columns=['name','gender','age','edu','age'])

在这里插入图片描述

#取出数据的中间三行,并返回姓名、年龄、和受教育水平三列
#iloc方法
df1.iloc[1:4,[0,3,2]]

在这里插入图片描述

#loc方法
#1:3为行标签,而非索引
df1.loc[1:3,['name','age','edu']]

在这里插入图片描述

加入数据集没有数值行号,而是具体的行名称,下面为此种情况下的方法:

#iloc 方法
df2.iloc[1:4,:]



#loc方法
df2.loc[['乙','丙','丁'],:]

在这里插入图片描述
但实际工作中,行的筛选很少通过指定的行索引或行名称进行,而是基于列的条件表达式获得的目标子集。

#返回所有男性的姓名,年龄和受教育水平
df1.loc[df1.gender=='男',['name','age','edu']]

在这里插入图片描述
结果显示,根据筛选条件的判断可以方便的将目标数据取出来,但需要注意的是,条件筛选只能使用在loc方法中。对变量的筛选,loc方法必须指定具体的变量名称

另关于data3中缺失行记录的删除也可以使用loc方法,具体如下:

data3_new=data3.loc[~data3['age'].isnull(),]
data3_new.shape

在这里插入图片描述
结果显示,同样可以得到2900行的数据子集,要注意的是,代码中判断条件data3[‘age’].isnull()前面必须加上"~"符号,它表示逻辑非操作,否则得到的将是缺失值所对应的行。

(3)多表合并与连接

如果对数据库SQL语法比较熟悉,那表之间的合并和连接就非常简单了。对于多张表的合并,只需要使用union或union all关键词;对于多张表之间的连接,只需要使用inner join或者left join即可
需要注意的是,对于多表之间的纵向合并,则必须确保多表的列数和数据类型必须一致;对于多表之间的水平扩展,则必须保证多表之间有共同的匹配变量;
对python来说,pandas提供了concat函数和merge函数
1)合并函数concat

pd.concat(objs,#指定需要合并的对象,可以是序列,数据框,或者面板数据构成的列表
          axis=0,#指定数据合并的轴,默认为0,表示合并多个数据的行(行数发生了变化),如果为1,则表示合并多个数据的列(列数发生了变化)
          join='outer',#指定合并的方式,默认为outer,表示合并所有的数据,如果改为inner,则表示合并公共部分的数据
          join_axes=None,#合并数据后,指定保留的数据轴
          ignore_index=False,#bool类型的参数,表示是否可以忽略原数据集的索引,默认为false,如果为True,则表示忽略原索引并生成新索引
          keys=None)#为合并后的数据添加新索引,用于区分各个数据部分

  • 2
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值