用python进行数据分析举例说明_利用Python进行数据分析实例练习

前面学习了Python的基础语法,Numpy和Pandas,终于要使用Python来进行数据分析的实战练习了。

本节以某药店2018年商品销售数据为例来练习利用Python进行数据分析的基本方法。

数据分析基本步骤: 1、提出问题 2、理解数据 3、数据清洗 4、构建模型 5、数据可视化

一、提出问题

要分析解决业务数据问题,首先要与业务部门进行沟通。本节案例主要分析月消费次数、月消费金额、客单价、消费趋势四大业务指标。对不理解的业务指标可以先自己去搜索引擎查找,实在找不到再去与业务人员沟通理解。

二、导入数据

注意在读取数据时可以先将所有数据按字符串读入,之后再转换为其他格式。

#导入数据分析包

import pandas as pd

'''路径中最好不要有中文,或者特殊符号啥的,不然路径会提示错误找不到。最好将文件放到一个简单的英文路径下'''

#excel文件路径,路径中的./表示在当前notebook所在的文件夹路径

fileNameStr=r'F:\数据分析\跟猴子学习人工智能核心技术\数据分析(高级)(Python)\第3关:数据分析的基本过程\朝阳医院2018年销售数据.xlsx'

'''使用pandas的read_excel函数读取Ecxcel数据参数sheet_name:数据在Excel里的哪个sheet下面,这块就写该sheet在excel里的名称参数dtype=str 统一先按照字符串读入,之后再转换pandas的read_excel函数官网地址:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_excel.html#pandas.read_excel'''

salesDf = pd.read_excel(fileNameStr,sheet_name='Sheet1',dtype=str)

#用pd.read_excel()方法也可以导入数据

salesDf=pd.read_excel(r'F:\数据分析\跟猴子学习人工智能核心技术\数据分析(高级)(Python)\第3关:数据分析的基本过程\朝阳医院2018年销售数据.xlsx',dtype='object')

print(salesDf.head())

购药时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额

0 2018-01-01 星期五 001616528 236701 强力VC银翘片 6 82.8 69

1 2018-01-02 星期六 001616528 236701 清热解毒口服液 1 28 24.64

2 2018-01-06 星期三 0012602828 236701 感康 2 16.8 15

3 2018-01-11 星期一 0010070343428 236701 三九感冒灵 1 28 28

4 2018-01-15 星期五 00101554328 236701 三九感冒灵 8 224 208

#有多少行,多少列

salesDf.shape

#查看每一列的数据类型

salesDf.dtypes

三、数据清洗

数据清洗的步骤花费时间最多,大概有80%的时间都用来进行数据清洗,不过清洗完成后数据运用起来就非常便捷了。

1)选择子集(本案例不需要选择子集)

#注释掉,.loc方法可以直接修改数据

#subSalesDf=salesDf.loc[0:4,'购药时间':'销售数量']

2)列名重命名

#字典:旧列名和新列名对应关系

colNameDict = {'购药时间':'销售时间'}

'''inplace=False,数据框本身不会变,而会创建一个改动后新的数据框,默认的inplace是Falseinplace=True,数据框本身会改动'''

salesDf.rename(columns = colNameDict,inplace=True)

salesDf.head()

销售时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额 0 2018-01-01 星期五 001616528 236701 强力VC银翘片 6 82.8 69 1 2018-01-02 星期六 001616528 236701 清热解毒口服液 1 28 24.64 2 2018-01-06 星期三 0012602828 236701 感康 2 16.8 15 3 2018-01-11 星期一 0010070343428 236701 三九感冒灵 1 28 28 4 2018-01-15 星期五 00101554328 236701 三九感冒灵 8 224 208

3.缺失数据处理

python缺失值有3种:

1)Python内置的None值

2)在pandas中,将缺失值表示为NA,表示不可用not available。

3)对于数值数据,pandas使用浮点值NaN(Not a Number)表示缺失数据。

后面出来数据,如果遇到错误:说什么foloat错误,那就是有缺失值,需要处理掉

所以,缺失值有3种:None,NA,NaN

print('删除缺失值前大小',salesDf.shape)

删除缺失值前大小 (6578, 7)

#删除列(销售时间,社保卡号)中为空的行

#subset=['销售时间','社保卡号'],表示对这两列的数据进行筛选

#how='any' 在给定的任何一列中有缺失值就删除

salesDf=salesDf.dropna(subset=['销售时间','社保卡号'],how='any')

#经过dropna处理,数据行数变少说明确实存在缺失数据

print('删除缺失后大小',salesDf.shape)

删除缺失后大小 (6575, 7)

4.数据类型转换

因为前面导入数据时将所有数据都转换成了字符串,所以这里要将数值列的字符串转换为数值(浮点型)

#字符串转换为数值(浮点型),astype可以将数据转换成不同类型

salesDf['销售数量'] = salesDf['销售数量'].astype('float')

salesDf['应收金额'] = salesDf['应收金额'].astype('float')

salesDf['实收金额'] = salesDf['实收金额'].astype('float')

print('转换后的数据类型:\n',salesDf.dtypes)

'''运行后,会报警告SettingWithCopyWarning一般信息有两列,一类是Warning警告信息,一类是Error错误信息。警告的信息不用管,我们只关注错误类型的信息'''

转换后的数据类型:

销售时间 object

社保卡号 object

商品编码 object

商品名称 object

销售数量 float64

应收金额 float64

实收金额 float64

dtype: object

'\n运行后,会报警告SettingWithCopyWarning\n一般信息有两列,一类是Warning警告信息,一类是Error错误信息。\n警告的信息不用管,我们只关注错误类型的信息\n'

字符串转换为日期数据类型

要先将字符串处理成为可以直接转换的形式(可以通过定义函数进行处理),在进行数据类型转换。

'''定义函数:分割销售日期,获取销售日期输入:timeColSer 销售时间这一列,是个Series数据类型输出:分割后的时间,返回也是个Series数据类型'''

def splitSaletime(timeColSer):

timeList=[]

for value in timeColSer:

#例如2018-01-01 星期五,分割后为:2018-01-01

dateStr=value.split(' ')[0]

timeList.append(dateStr)

#将列表转行为一维数据Series类型

timeSer=pd.Series(timeList)

return timeSer

#获取“销售时间”这一列

timeSer=salesDf.loc[:,'销售时间']

#对字符串进行分割,获取销售日期

dateSer=splitSaletime(timeSer)

'''注意:如果运行后报错:AttributeError: 'float' object has no attribute 'split'是因为Excel中的空的cell读入pandas中是空值(NaN),这个NaN是个浮点类型,一般当作空值处理。所以要先去除NaN在进行分隔字符串'''

#修改销售时间这一列的值

salesDf.loc[:,'销售时间']=dateSer

salesDf.head()

销售时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额 0 2018-01-01 001616528 236701 强力VC银翘片 6.0 82.8 69.00 1 2018-01-02 001616528 236701 清热解毒口服液 1.0 28.0 24.64 2 2018-01-06 0012602828 236701 感康 2.0 16.8 15.00 3 2018-01-11 0010070343428 236701 三九感冒灵 1.0 28.0 28.00 4 2018-01-15 00101554328 236701 三九感冒灵 8.0 224.0 208.00

'''数据类型转换:字符串转换为日期'''

#errors='coerce' 如果原始数据不符合日期的格式,转换后的值为空值NaT

#format 是你原始数据中日期的格式

salesDf.loc[:,'销售时间']=pd.to_datetime(salesDf.loc[:,'销售时间'],

format='%Y-%m-%d',

errors='coerce')

salesDf.dtypes

销售时间 datetime64[ns]

社保卡号 object

商品编码 object

商品名称 object

销售数量 float64

应收金额 float64

实收金额 float64

dtype: object

#清洗数据的过程中要注意是否会产生新的空值,如果产生了要及时删除

'''转换日期过程中不符合日期格式的数值会被转换为空值,这里删除列(销售时间,社保卡号)中为空的行'''

salesDf=salesDf.dropna(subset=['销售时间','社保卡号'],how='any')

5.数据排序

print('排序前的数据集')

salesDf.head()

排序前的数据集

销售时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额 0 2018-01-01 001616528 236701 强力VC银翘片 6.0 82.8 69.00 1 2018-01-02 001616528 236701 清热解毒口服液 1.0 28.0 24.64 2 2018-01-06 0012602828 236701 感康 2.0 16.8 15.00 3 2018-01-11 0010070343428 236701 三九感冒灵 1.0 28.0 28.00 4 2018-01-15 00101554328 236701 三九感冒灵 8.0 224.0 208.00

'''by:按哪几列排序ascending=True 表示升序排列,ascending=True表示降序排列na_position=True表示排序的时候,把空值放到前列,这样可以比较清晰的看到哪些地方有空值官网文档:https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.sort_values.html'''

#按销售日期进行升序排列

salesDf=salesDf.sort_values(by='销售时间',

ascending=True,

na_position='first')

print('排序后的数据集')

salesDf.head(5)

排序后的数据集

销售时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额 0 NaT 0010074055328 2367010 高特灵 2.0 11.2 10.0 1 NaT 0010018771328 2367011 开博通 2.0 56.0 50.0 2 NaT 0010030713228 2367011 开博通 4.0 112.0 106.0 3 NaT 0010045707528 2367011 开博通 10.0 280.0 274.0 4 NaT 001616528 2367011 开博通 4.0 112.0 112.0

#日期列存在空值,需将其删除

salesDf=salesDf.dropna(subset=['销售时间'],how='any')

#重命名行名(index):排序后的列索引值是之前的行号,需要修改成从0到N按顺序的索引值,drop=True不保留之前的索引

salesDf=salesDf.reset_index(drop=True)

salesDf.head()

销售时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额 0 2018-01-01 001616528 236701 强力VC银翘片 6.0 82.8 69.0 1 2018-01-01 0011743428 861405 苯磺酸氨氯地平片(络活喜) 1.0 34.5 31.0 2 2018-01-01 0010616728 865099 硝苯地平片(心痛定) 2.0 3.4 3.0 3 2018-01-01 0010073966328 861409 非洛地平缓释片(波依定) 5.0 162.5 145.0 4 2018-01-01 0010014289328 866851 缬沙坦分散片(易达乐) 1.0 26.0 23.0

6.异常值处理

#描述指标:查看出“销售数量”值不能小于0

salesDf.describe()

#删除异常值:通过条件判断筛选出数据

#查询条件

querySer=salesDf.loc[:,'销售数量']>0

#应用查询条件

print('删除异常值前:',salesDf.shape)

salesDf=salesDf.loc[querySer,:]

print('删除异常值后:',salesDf.shape)

四、构建模型

数据清洗完毕,利用新的数据对业务指标进行分析。

业务指标1:月均消费次数=总消费次数 / 月份数

'''总消费次数:同一天内,同一个人发生的所有消费算作一次消费#根据列名(销售时间,社区卡号),如果这两个列值同时相同,只保留1条,将重复的数据删除'''

#subset=['销售时间', '社保卡号'],只有两列的数据完全相同才会背作为重复数据删除

kpi1_Df=salesDf.drop_duplicates(

subset=['销售时间', '社保卡号']

)

#总消费次数:有多少行

totalI=kpi1_Df.shape[0]

print('总消费次数=',totalI)

总消费次数= 5375

'''计算月份数:时间范围'''

#第1步:按销售时间升序排序

kpi1_Df=kpi1_Df.sort_values(by='销售时间',

ascending=True)

#重命名行名(index)

kpi1_Df=kpi1_Df.reset_index(drop=True)

kpi1_Df.head()

销售时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额 0 2018-01-01 001616528 236701 强力VC银翘片 6.0 82.8 69.0 1 2018-01-01 0013331728 861405 苯磺酸氨氯地平片(络活喜) 2.0 69.0 62.0 2 2018-01-01 0010017493928 868042 马来酸左旋氨氯地平片(玄宁) 1.0 46.0 46.0 3 2018-01-01 0010074599128 874684 厄贝沙坦氢氯噻嗪片(依伦平) 5.0 118.0 118.0 4 2018-01-01 00107891628 868107 厄贝沙坦氢氯噻嗪片(安博诺) 1.0 38.8 35.0

#第2步:获取时间范围

#最小时间值

startTime=kpi1_Df.loc[0,'销售时间']

#最大时间值

endTime=kpi1_Df.loc[totalI-1,'销售时间']

#第3步:计算月份数

#天数

daysI=(endTime-startTime).days

#月份数: 运算符“//”表示取整除

#返回商的整数部分,例如9//2 输出结果是4

monthsI=daysI//30

print('月份数:',monthsI)

月份数: 6

#业务指标1:月均消费次数=总消费次数 / 月份数

kpi1_I=totalI // monthsI

print('业务指标1:月均消费次数=',kpi1_I)

业务指标1:月均消费次数= 895

指标2:月均消费金额 = 总消费金额 / 月份数

#总消费金额

totalMoneyF=salesDf.loc[:,'实收金额'].sum()

#月均消费金额

monthMoneyF=totalMoneyF / monthsI

print('业务指标2:月均消费金额=',monthMoneyF)

业务指标2:月均消费金额= 50519.38999999966

指标3:客单价=总消费金额 / 总消费次数

客单价(per customer transaction)是指商场(超市)每一个顾客平均购买商品的金额,客单价也即是平均交易金额。

'''totalMoneyF:总消费金额totalI:总消费次数'''

pct=totalMoneyF / totalI

print('客单价:',pct)

客单价: 56.39373767441822

指标4:消费趋势,画图:折线图

指标4的分析将在下节利用高阶Pandas功能和Matplotlib来实现。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值