重点客户销售数据分析python_药品销售数据分析--python

一、数据分析的目的

数据分析是指用适当的统计分析方法对收集来的大量数据进行分析,提取有用信息和形成结论而对数据加以详细研究和概括总结的过程。

本篇文章中,假设以朝阳医院2018年销售数据为例,目的是了解朝阳医院在2018年里的销售情况,这就需要知道几个业务指标,例如:月均消费次数,月均消费金额、客单价以及消费趋势

二、数据分析基本过程

数据分析基本过程包括:获取数据、数据清洗、构建模型、数据可视化以及消费趋势分析。

python先导入包,然后读取文件,读取的时候用object读取,防止有些数据读不了:

import numpy as np

from pandas import Series,DataFrame

import pandas as pd

#导入数据

file_name = '朝阳医院2018年销售数据.xlsx'

xls = pd.ExcelFile(file_name)

dataDF = xls.parse('Sheet1',dtype='object')

print(dataDF.head())

image.png

查看数据基本信息:

#查看基本信息

#查看数据几行几列

print(dataDF.shape)

#查看索引

print(dataDF.index)

#查看每一列的列表头内容

print(dataDF.columns)

#查看每一列数据统计数目

print(dataDF.count())

image.png

总共有6578行7列数据,但是“购药时间”和“社保卡号”这两列只有6576个数据,而“商品编码”一直到“实收金额”这些列都是只有6577个数据,这就意味着数据中存在缺失值,可以推断出数据中存在一行缺失值,此外“购药时间”和“社保卡号”这两列都各自存在一个缺失数据,这些缺失数据在后面步骤中需要进一步处理。

2.数据清洗

数据清洗过程包括:选择子集、列名重命名、缺失数据处理、数据类型转换、数据排序及异常值处理

(1)选择子集

在我们获取到的数据中,可能数据量非常庞大,并不是每一列都有价值都需要分析,这时候就需要从整个数据中选取合适的子集进行分析,这样能从数据中获取最大价值。在本次案例中不需要选取子集,暂时可以忽略这一步。

(2)列重命名

在数据分析过程中,有些列名和数据容易混淆或产生歧义,不利于数据分析,这时候需要把列名换成容易理解的名称,可以采用rename函数实现:

#列重命名

dataDF.rename(columns={'购药时间':'销售时间'},inplace=True)

print(dataDF.head())

image.png

(3)缺失值处理

获取的数据中很有可能存在缺失值,通过查看基本信息可以推测“购药时间”和“社保卡号”这两列存在缺失值,如果不处理这些缺失值会干扰后面的数据分析结果。缺失数据常用的处理方式为删除含有缺失数据的记录或者利用算法去补全缺失数据。在本次案例中为求方便,直接使用dropna函数删除缺失数据,具体如下:

#缺失值处理

print('删除缺失值前:', dataDF.shape)

print(dataDF.info())

#删除缺失值

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

print('\n删除缺失值后',dataDF.shape)

print(dataDF.info())

image.png

(4)数据类型转换

在导入数据时为了防止导入不进来,会强制所有数据都是object类型,但实际数据分析过程中“销售数量”,“应收金额”,“实收金额”,这些列需要浮点型(float)数据,“销售时间”需要改成时间格式,因此需要对数据类型进行转换。

可以使用astype()函数转为浮点型数据:

#数据类型转换

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

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

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

print(dataDF.dtypes)

image.png

在“销售时间”这一列数据中存在星期这样的数据,但在数据分析过程中不需要用到,因此要把销售时间列中日期和星期使用split函数进行分割,分割后的时间,返回的是Series数据类型:

#定义函数将星期除去

def splitSaletime(timeColser):

timelist =[]

for val in timeColser:

data = val.split(' ')[0]

timelist.append(data)

#将列表转为Series类型

timeSer = Series(timelist)

return timeSer

#获取"销售时间"这一列数据

time = dataDF.loc[:,'销售时间']

#调用函数去除星期,获得日期

data = splitSaletime(time)

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

dataDF.loc[:,'销售时间'] = data

print(dataDF.head())

image.png

接着把切割后的日期转为时间格式,方便后面的数据统计:

#字符串转日期

dataDF.loc[:,'销售时间'] = pd.to_datetime(dataDF.loc[:,'销售时间'], format='%y-%m-%d', errors='coerce')

print(dataDF.dtypes)

#在日期转换过程中不符合日期格式的会转换为空值,这里需要删除

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

image.png

(5)数据排序

此时时间是没有按顺序排列的,所以还是需要排序一下,排序之后索引会被打乱,所以也需要重置一下索引。其中by:表示按哪一列进行排序,ascending=True表示升序排列,ascending=False表示降序排列

#数据排序

dataDF = dataDF.sort_values(by='销售时间', ascending=True)

dataDF = dataDF.reset_index(drop=True)

print(dataDF.head())

image.png

(6)异常值处理

先查看数据的描述统计信息

#查看描述统计信息

print(dataDF.describe())

image.png

通过描述统计信息可以看到,“销售数量”、“应收金额”、“实收金额”这三列数据的最小值出现了负数,这明显不符合常理,数据中存在异常值的干扰,因此要对数据进一步处理,以排除异常值的影响:

#将'销售数量'这一列小于0的数据排除掉

pop = dataDF.loc[:,'销售数量'] > 0

dataDF = dataDF.loc[pop,:]

print(dataDF.describe())

image.png

三、构建模型及数据可视化

数据清洗完成后,需要利用数据构建模型(就是计算相应的业务指标),并用可视化的方式呈现结果。

(1)业务指标1:月均消费次数

月均消费次数 = 总消费次数 / 月份数(同一天内,同一个人所有消费算作一次消费)

#计算总消费次数

#删除重复数据

kpil_Df = dataDF.drop_duplicates(subset=['销售时间','社保卡号'])

totalI = kpil_Df.shape[0]

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

#计算月份数

#按销售时间升序排序

kpil_Df = kpil_Df.sort_values(by='销售时间', ascending=True)

#重命名行名

kpil_Df = kpil_Df.reset_index(drop=True)

#获取时间范围

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

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

#计算月份

#天数

daysI = (endTime-startTime).days

mounthI = daysI//30

print('月份数=',mounthI)

#月平均消费次数

kpil_I = totalI//mounthI

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

image.png

(2)业务指标2:月均消费金额

月均消费金额 = 总消费金额 / 月份数

#消费总金额

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

mounthMoney = totalMoneyF // mounthI

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

image.png

(3)客单价

客单价 = 总消费金额 / 总消费次数

#客单价

pct = totalMoneyF / totalI

print('业务指标3:客单价=', pct)

image.png

(4)消费趋势

a. 导入python可视化相关的包

import matplotlib.pyplot as plt

import matplotlib

#画图时用于显示中文字符

from pylab import mpl

mpl.rcParams['font.sans-serif'] = ['SimHei'] # SimHei是黑体的意思

#在操作之前先复制一份

b. 分析每天的消费金额

#mpl.rcParams['font.sans-serif'] = ['Songti'] # SimHei是黑体的意思

font = FontProperties(fname='/Library/Fonts/Songti.ttc') #设置字体

#在操作之前先复制一份数据,防止影响清洗后的数据

groupDF = dataDF

#将'销售时间'设置为index

groupDF.index = groupDF['销售时间']

print(groupDF.head())

gb = groupDF.groupby(groupDF.index)

print(gb)

dayDF = gb.sum()

print(dayDF)

#画图

plt.plot(dayDF['实收金额'])

plt.title('按天消费金额',fontproperties=font)

plt.xlabel('时间',fontproperties=font)

plt.ylabel('实收金额',fontproperties=font)

plt.show()

image.png

image.png

从结果可以看出,每天消费总额差异较大,除了个别天出现比较大笔的消费,大部分人消费情况维持在1000-2000元以内。

c. 分析每月的消费金额

接下来,我销售时间先聚合再按月分组进行分析:

#将销售时间聚合按月分组

gb = groupDF.groupby(groupDF.index.month)

print(gb)

monthDF = gb.sum()

print(monthDF)

plt.plot(monthDF['实收金额'])

plt.title('按月消费金额',fontproperties=font)

plt.xlabel('时间',fontproperties=font)

plt.ylabel('实收金额',fontproperties=font)

plt.show()

image.png

image.png

结果显示,7月消费金额最少,这是因为7月份的数据不完整,所以不具参考价值。

1月、4月、5月和6月的月消费金额差异不大,2月和3月的消费金额迅速降低,这可能是2月和3月处于春节期间,大部分人都回家过年的原因。

d. 分析药品销售情况

对“商品名称”和“销售数量”这两列数据进行聚合为Series形式,方便后面统计,并按降序排序:

#聚合统计各种药品数量

medicine = groupDF[['商品名称','销售数量']]

bk = medicine.groupby('商品名称')[['销售数量']]

re_medicine = bk.sum()

#对销售药品数量按将序排序

re_medicine = re_medicine.sort_values(by='销售数量', ascending=False)

print(re_medicine.head())

image.png

截取销售数量最多的前十种药品,并用条形图展示结果:

top_medicine = re_medicine.iloc[:10,:]

print(top_medicine)

image.png

image.png

得到销售数量最多的前十种药品信息,这些信息将会有助于加强医院对药房的管理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/298061.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#类与结构体究竟谁快——各种函数调用模式速度评测

以前我一直有个疑惑——在C#中,究竟是类(class)比较快,还是结构体(struct)比较快?当时没有深究。 最近我遇到一个难题,需要将一些运算大的指针操作代码给封装一下。原先为了性能&…

HelloSilverlight

一&#xff1a;输入姓名并选中一个日期&#xff0c;将在下面显示 二:XAML代码 <UserControl x:Class"HelloSilverlight.MainPage"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2…

Building a Space Station--POJ 2031

1、题目类型&#xff1a;计算几何&#xff0c;最小生成树。 2、解题思路&#xff1a;&#xff08;1&#xff09;获得所有点路径长度的矩阵map[][]&#xff1b;&#xff08;2&#xff09;利用Prim算法求解最小生成树。 3、注意事项&#xff1a;数学操作&#xff0c;中间值全部用…

21世纪7大数学难题,解决其中一个你就成为了百万富翁!

全世界只有3.14 % 的人关注了爆炸吧知识百万富翁你也可以昨天一大早&#xff0c;知识君就收到模友送的3枝红玫瑰。仔细一看&#xff0c;原来又是来跟知识君约稿的。。。知识君只能说&#xff1a;1900年&#xff0c;希尔伯特&#xff08;传送门&#xff09;在巴黎国际数学家代表…

在 Azure VM 上使用 Jitsi 搭建私人视频会议

点击上方蓝字 / 关注“汪宇杰博客”原文&#xff1a;Azure Tips And Tricks翻译&#xff1a;汪宇杰私人视频会议市面上有许多视频会议应用程序&#xff0c;例如 Zoom、Microsoft Teams 和 Skype。有时&#xff0c;您需要自己的服务&#xff0c;以让自己更安全并在自己的公司内部…

php 筛选数组,2020-07-24 php 通过数组键值对筛选数组

筛选数组 $listMenuArray([0] > Array([type] > 0[min] > 0)[1] > Array([type] > 1[min] > 1))目标数组 $resArray([0] > Array([id] > 183[type] > 0[min] > 0)[1] > Array([id] > 184[type] > 0[min] > 1)[2] > Array([id] &g…

python省市区三级联动_Django Admin实现三级联动的示例代码(省市区)

通过自定义Admin的模板文件实现省市区的三级联动.要求创建记录时,根据省>市>区的顺序选择依次显示对应数据.修改记录时默认显示已存在的数据.Modelclass Member(models.Model):name models.CharField(max_length100, verbose_name姓名)province models.CharField(max_l…

[LeetCode]119.Pascal#39;s Triangle II

题目 Given an index k, return the kth row of the Pascal’s triangle. For example, given k 3, Return [1,3,3,1]. Note: Could you optimize your algorithm to use only O(k) extra space? 思路 无 代码 /**------------------------------------* 日期&#xff1a…

2010.7.29 模式对话框

为什么点击ONOK后&#xff0c;对话框上的控件资源会被删除&#xff1f;OnOK做了什么事儿&#xff1f; 假如有一个对话框Class CMyDialog 我在CMyDialog中&#xff0c;声明了一个m_button&#xff0c;然后在OnInitDlg()中create这个buttton&#xff0c;即m_button.create() 然后…

终于有人做了我一直想做而不敢做的事。。

1 初中物理是不是学过&#xff0c;受力面积小&#xff0c;相应的压力就大&#xff5e;我觉得应该直接趴上去&#xff0c;一定行&#xff5e;反正我也是瞎说的2 不是我吹&#xff0c;换成是我&#xff0c;这包子能吃五屉3 交警蜀黍耐心的领着这位行人过马路&#xff0c;麻烦你快…

.NET 6 中的隐式命名空间引用

.NET 6 中的隐式命名空间引用Intro之前写过一篇隐式命名空间引用的大概介绍&#xff0c;在一些小的测试项目中也有在用&#xff0c;一直没作为示例给大家分享&#xff0c;主要原因在于之前看到了一个关于隐式命名空间引用的 Github issue 提到会有一些破坏性的变更&#xff0c;…

vscode函数跳转插件_人生苦短,我们为 Cocos Creator 开发的插件和工具

在使用 Cocos Creator 开发项目的过程中&#xff0c;为了提高开发效率我们开发了很多扩展插件&#xff0c;本文介绍常用的几款&#xff0c;抛砖引玉&#xff0c;希望给大家带来帮助。腾讯开心鼠英语网页扩展&#xff1a;运行时查看场景节点树Cocos Creator 本地项目通常会在 Ch…

SQLSERVER 日志收缩

SQL2008 的收缩日志 由于SQL2008对文件和日志管理进行了优化&#xff0c;所以以下语句在SQL2005中可以运行但在SQL2008中已经被取消&#xff1a;(SQL2005)BackupLog DNName with no_loggodumptransaction DNName with no_loggoUSE DNName DBCC SHRINKFILE (2)Go---------------…

压缩JS和CSS常用的工具

前些时候在发现将 JS和CSS压缩一下&#xff0c;的确有好处。在网上找了一下&#xff0c;发现下面的两款工具比较不错。 经过资源&#xff08;比如 CSS 和 JavaScrip 文件&#xff09;压缩测试了。 其中一个工具就是 YUI Compressor&#xff0c;一个来自Yahoo! Developer Networ…

php+转义实体字符,PHP针对HTML实体字符的转义函数

htmlspecialchars()转义特别的字符为HTML实体&#xff1b;& (ampersand) becomes & " (double quote) becomes " when ENT_NOQUOTES is not set. (single quote) becomes only when ENT_QUOTES is set. (greater than) becomes >htmlspeci…

解决win7“该文件没有与之关联的程序来执行该操作”

机器装好了win7系统。右击“计算机”管理的时候&#xff0c;出现“该文件没有与之关联的程序来执行该操作”能是因为删除了start menu下的某个文件,经过分析,找到了如下的解决方法:定位到注册表HKEY_CLASSES_ROOT\CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\shell\Manage\c…

绝不能放进微波炉的10样东西,最后一个太意外

全世界只有3.14 % 的人关注了爆炸吧知识前一阵&#xff0c;网上有一段用微波炉加热葡萄的视频&#xff0c;成了新闻热点。研究员在实验中发现&#xff0c;两颗葡萄放进微波炉后&#xff0c;竟然会产生电弧。图片来源网络之前小编加热汉堡的时候&#xff0c;本来想大快朵颐一顿&…

在 .NET 6 中使用 DATEONLY 和 TIMEONLY

在 .NET 6 中使用 DATEONLY 和 TIMEONLY在 即将发布的.NET 6中&#xff0c;引入了两种期待已久的类型作为核心库的一部分。DateOnly和TimeOnly允许开发人员表示 DateTime 的日期或时间部分。这两种新类型是结构体&#xff08;值类型&#xff09;&#xff0c;可以在您的代码独立…

vue 3.0 正式版_Vuejs 3 Release:One Piece. Vuejs 3.0 正式版发布!代号:海贼王

Vuejs 3.0 在北京时间2020年9月19日凌晨&#xff0c;终于发布了 3.0 版本&#xff0c;代号&#xff1a;One Piece。此次vue3.0 为用户提供了全新的 composition-api 以及更小的包大小&#xff0c;和更好的 TypeScript 支持。Vue3.0发布链接​github.comVue 是当前非常流行的框架…

i-doIT 0.9.9-7发布 CMDB配置管理数据库

i-doIT是一个基于ITIL技术的CMDB&#xff08;配置管理数据库&#xff09;。它能够记载IT系统及其变化&#xff0c;对变化定义了应急方案&#xff0c;以及显示重要信息&#xff0c;并有助于确保一个稳定和高效的IT网络运作。由于其模块化的架构&#xff0c;它可以部署功能性的附…