作者:kaining_huang_750 | 来源:互联网 | 2023-08-30 09:00
用Python中的NumPy和Pandas数据分析包对某医院的销售数据进行分析,数据分析的基本流程为:提出问题、理解数据(数据采集、数据导入、查看数据集信息)、数据清洗、建构模型、
用Python中的NumPy和Pandas数据分析包对某医院的销售数据进行分析,数据分析的基本流程为:提出问题、理解数据(数据采集、数据导入、查看数据集信息)、数据清洗、建构模型、数据可视化。
import numpy as np
import pandas as pd
从销售数据中分析出以下任务指标:
1)月均消费次数 2)月均消费金额 3)客单价
读取数据
#读取Ecxcel数据,统一先按照字符串读入,之后转换
fileNameStr='./朝阳医院2018年销售数据.xlsx'
xls = pd.ExcelFile(fileNameStr, dtype='object')
salesDf = xls.parse('Sheet1',dtype='object')
'''
查看数据基本信息
'''
#打印出前5行,以确保数据运行正常
salesDf.head()
![《Python数据分析实战——医院销售数据分析》](https://img.php1.cn/3cd4a/1eebe/cd5/eec57030b649a106.webp)
读取并查看数据
#有多少行,多少列
salesDf.shape
(6578, 7)
#查看每一列的数据类型
salesDf.dtypes
购药时间 object
社保卡号 object
商品编码 object
商品名称 object
销售数量 object
应收金额 object
实收金额 object
dtype: object
数据清洗
#subSalesDf=salesDf.loc[0:4,'购药时间':'销售数量'] #选择子集
#列名重命名
#字典:旧列名和新列名对应关系
colNameDict = {'购药时间':'销售时间'}
'''
inplace=False,数据框本身不会变,而会创建一个改动后新的数据框,默认的inplace是False
inplace=True,数据框本身会改动
'''
salesDf.rename(columns = colNameDict,inplace=True)
salesDf.head()
![《Python数据分析实战——医院销售数据分析》](https://img.php1.cn/3cd4a/1eebe/cd5/0ef126b5295c089b.webp)
列名重命名
缺失值处理
print('删除缺失值前大小',salesDf.shape)
删除缺失值前大小 (6578, 7)
#删除列(销售时间,社保卡号)中为空的行
#how='any' 在给定的任何一列中有缺失值就删除
salesDf=salesDf.dropna(subset=['销售时间','社保卡号'],how='any')
print('删除缺失后大小',salesDf.shape)
删除缺失后大小 (6575, 7)
数据类型转化
#字符串转换为数值(浮点型)
salesDf['销售数量'] = salesDf['销售数量'].astype('float')
salesDf['应收金额'] = salesDf['应收金额'].astype('float')
salesDf['实收金额'] = salesDf['实收金额'].astype('float')
#字符串分割
testList='2018-06-03 星期五'.split(' ')
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)
salesDf.loc[:,'销售时间']=dateSer
'''
数据类型转换:字符串转换为日期
'''
#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')
数据排序
'''
by:按那几列排序
ascending=True 表示降序排列,
ascending=False表示升序排列
'''
#按销售日期进行升序排列
salesDf=salesDf.sort_values(by='销售时间',ascending=True)
#重命名行名(index):排序后的列索引值是之前的行号,需要修改成从0到N按顺序的索引值
salesDf=salesDf.reset_index(drop=True)
salesDf.head()
异常值处理
salesDf.describe()
#发现存在销售数量<0的异常值
#删除异常值:通过条件判断筛选出数据
#查询条件
querySer=salesDf.loc[:,'销售数量']>0
#应用查询条件
print('删除异常值前:',salesDf.shape)
salesDf=salesDf.loc[querySer,:]
print('删除异常值后:',salesDf.shape)
删除异常值前: (6533, 7)
删除异常值后: (6506, 7)
构建模型
指标1:月均消费次数
'''
总消费次数:同一天内,同一个人发生的所有消费算作一次消费
#根据列名(销售时间,社区卡号),如果这两个列值同时相同,只保留1条,将重复的数据删除
'''
kpi1_Df=salesDf.drop_duplicates(subset=['销售时间', '社保卡号'])
#总消费次数:有多少行
totalI=kpi1_Df.shape[0]
print('总消费次数=',totalI)
总消费次数= 5342
#月份数
startTime=kpi1_Df.loc[0,'销售时间']
endTime=kpi1_Df.loc[totalI-1,'销售时间']
daysI=(endTime-startTime).days
mOnthsI=daysI//30
print('月份数:',monthsI)
月份数: 6
#业务指标1:月均消费次数=总消费次数 / 月份数
kpi1_I=totalI // monthsI
print('业务指标1:月均消费次数=',kpi1_I)
业务指标1:月均消费次数= 890
指标2:月均消费金额
#总消费金额
totalMOneyF=salesDf.loc[:,'实收金额'].sum()
#月均消费金额
mOnthMoneyF=totalMoneyF / monthsI
print('业务指标2:月均消费金额=',monthMoneyF)
业务指标2:月均消费金额= 50668
指标3:客单价
'''
totalMoneyF:总消费金额
totalI:总消费次数
'''
pct=totalMoneyF / totalI
print('客单价:',pct)
客单价: 57