大数据分析——某电商平台药品销售数据分析

一、   选题背景

  我们已经习惯了在网上购买衣服、数码产品和家用电器,但是在网上买药品的还是不多。据史国网上药店理事会调查报告显示:2022 年,医药 B2C 的规模达到 4 亿元,仅出现 5 家锁售额达.5000 万元的网上药店。而 2022 年医药行业的市场规模达到3718 亿,线上药品的销售额还不到网下药店的一个零头,还有很大的发展潜力。大数据的不断发展影响消费者生活的各个方面,也对企业的营销模式提出挑站对大 数据量化分析,分析数据中的相关性分析,单因素分析等技术对消费者相关数据进行分析,能够挖掘出对企业真正有意义的信息。这就要求企业在有现的人力、物力资源下, 更新并找出合理的销售方案。对于医药企业来说,大数据为企业带来了危机也带来了商机,企业应根据自身发展阶段及药品特征,以及顾客价值最大化作为方向,以信息化为手段,并根据市场对药品需求的变化,把握消费者的个性需求,进行精准营销,与消费者建立起良性有效的互动,及时获得消费者反馈,整合传统媒体与新媒体宣传资源,选择合适的企业发展的营销战略。

二、   大数据分析设计方案

1.本数据集的数据内容数据特征分析

  本数据集是一份网络电商平台的药品销售数据集,共7个字段,包括购药时间(string),社保卡号(int),商品编码(int),商品名称(string),销售数量(int),应收金额(int),实收金额(int)。

 

外卖平台大数据分析案例 大数据对外卖行业分析_数据集

2.数据分析的课程设计方案概述

(1)先对数据进行预处理和清洗

(2)数据分析和可视化

(3)随机森林填补缺失值

三、数据分析步骤

1.数据源

  数据集来源于国外Kaggle数据集网站进行采集。源数据集网址

  https://www.kaggle.com/datasets/jack20216915/yaopin

导入库

1 import pandas as pd
 2 import stylecloud
 3 from PIL import Image
 4 from collections import Counter
 5 from pyecharts.charts import Bar
 6 from pyecharts.charts import Line
 7 from pyecharts.charts import Calendar
 8 from pyecharts import options as opts
 9 from pyecharts.commons.utils import JsCode
10 from pyecharts.globals import SymbolType

读取数据集

1 df = pd.read_excel('电商平台药品销售数据.xlsx')
2 df.head(10)

外卖平台大数据分析案例 大数据对外卖行业分析_数据_02

 2数据清洗

  数据清洗, 是整个数据分析过程中不可缺少的一个环节,其结果质量直接关系到模型效果和最终结论。在实际操作中,数据清洗通常会占据分析过程的50%—80%的时间。

(1)查看索引、数据类型和内存信息

  info() 函数用于打印 DataFrame 的简要摘要,显示有关 DataFrame 的信息,包括索 引的数据类型 dtype 和列的数据类型 dtype,非空值的数量和内存使用情况

1 df.info()

外卖平台大数据分析案例 大数据对外卖行业分析_数据集_03

(2)统计空值数据

  使用 isnull() 函数时不需要传入任何参数,只需要使用 df 对象去调用它就可以了。 该方法运行之后会将整个表格对象内的所有数据都转为 True 值以及 False 值,其中 NaN 值转换之后得到就是 True

1 df.isnull().sum()

外卖平台大数据分析案例 大数据对外卖行业分析_数据_04

(3) 输出包含空值的行

外卖平台大数据分析案例 大数据对外卖行业分析_柱状图_05

   因为购药时间在后面的分析中会用到,所以我们将购药时间为空的行删除

外卖平台大数据分析案例 大数据对外卖行业分析_柱状图_06

 (4)社保卡号用”000” 填充

fillna() 函数的功能: 该函数的功能是用指定的值去填充 dataframe 中的缺失值

1 df1['社保卡号'].fillna('0000', inplace=True)
2 df1.isnull().sum()

外卖平台大数据分析案例 大数据对外卖行业分析_外卖平台大数据分析案例_07

此时可以看到没有空值了

 (5)社保卡号、商品编码为一串数字,应为 str 类型,销售数量应为 int 类型

1 df1['社保卡号'] = df1['社保卡号'].astype(str)
2 df1['商品编码'] = df1['商品编码'].astype(str)
3 df1['销售数量'] = df1['销售数量'].astype(int)
4 df1.info()
5 df1.head()

外卖平台大数据分析案例 大数据对外卖行业分析_数据_08

  虽然这里强制转换社保卡号、商品编码为 str 类型,但是在读取表格的时候是以 float 读取的,所以存在小数点,这里我们可以在读取表格文件时指定相应列的数据类型 (需要注意如果数据存在空值,那么转换数值型时会失效):

1 df_tmp = pd.read_excel('电商平台药品销售数据.xlsx', converters={'社保卡号':str, '商品编码':str, '销售数量':int})
2 df_tmp.head()

外卖平台大数据分析案例 大数据对外卖行业分析_数据_09

 (6)销售数量、应收金额、实收金额分布情况

1 df2 = df_tmp.copy()
2 df2 = df2.dropna(subset=['购药时间'])
3 df2['社保卡号'].fillna('0000', inplace=True)
4 df2['销售数量'] = df2['销售数量'].astype(int)
5 df2[['销售数量','应收金额','实收金额']].describe()

外卖平台大数据分析案例 大数据对外卖行业分析_柱状图_10

 数据中存在负值,显然不合理,我们看一下负值所在的行

1 df2.loc[(df2['销售数量'] < 0)]

外卖平台大数据分析案例 大数据对外卖行业分析_柱状图_11

(7)负值转正值

 abs 是 python 的绝对值函数,计算绝对值,数据值转为正值

1 df2['销售数量'] = df2['销售数量'].abs()
2 df2['应收金额'] = df2['应收金额'].abs()
3 df2['实收金额'] = df2['实收金额'].abs()
4 df2.loc[(df2['销售数量'] < 0) | (df2['应收金额'] < 0) | (df2['实收金额'] < 0)].sum()

外卖平台大数据分析案例 大数据对外卖行业分析_柱状图_12

 

 (8)列拆分(购药时间列拆分为两列)

  对字符串按照指定规则分割,并将分割后的字段作为 list 返回,对购药日期和星期 两列进行分隔,进行列拆分

1 df3 = df2.copy()
2 df3[['购药日期', '星期']] = df3['购药时间'].str.split(' ', 2, expand = True)
3 df3 = df3[['购药日期', '星期','社保卡号','商品编码', '商品名称', '销售数量', '应收金额', '实收金额' ]]
4 df3

外卖平台大数据分析案例 大数据对外卖行业分析_柱状图_13

(9) 数据时间范围

  unique 函数去除其中重复的元素,并按元素由大到小返回一个新的无元素重复的元组或者列表

1 len(df3['购药日期'].unique())
2 df3.groupby('购药日期').sum()

外卖平台大数据分析案例 大数据对外卖行业分析_柱状图_14

  一共201个购买日期,时间范围2016-01-01至2016-07-19

3数据可视化

  “pyecharts 是一个用于生成 Echarts 图表的类库。Echarts 是百度开源的一个数据可视化 JS 库。用 Echarts 生成的图可视化效果非常棒,为了与 Python 进行对接,方便在 Python 中直接使用数据生成图”。
  pyecharts可以展示动态图,在线报告使用比较美观,并且展示数据方便,鼠标悬停在图上,即可显示数值、标签等。

(1)一周各天药品销量柱状图

1 color_js = """new echarts.graphic.LinearGradient(0, 1, 0, 0,
 2     [{offset: 0, color: '#FFFFFF'}, {offset: 1, color: '#ed1941'}], false)"""
 3 
 4 g1 = df3.groupby('星期').sum()
 5 x_data = list(g1.index)
 6 y_data = g1['销售数量'].values.tolist()
 7 b1 = (
 8         Bar()
 9         .add_xaxis(x_data)
10         .add_yaxis('',y_data ,itemstyle_opts=opts.ItemStyleOpts(color=JsCode(color_js)))
11         .set_global_opts(title_opts=opts.TitleOpts(title='一周各天药品销量',pos_top='2%',pos_left = 'center'),
12             legend_opts=opts.LegendOpts(is_show=False),
13             xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-15)),
14             yaxis_opts=opts.AxisOpts(name="销量",name_location='middle',name_gap=50,name_textstyle_opts=opts.TextStyleOpts(font_size=16)))
15 
16     )
17 b1.render('一周各天药品销量柱状图.html')

外卖平台大数据分析案例 大数据对外卖行业分析_数据集_15

  从下图可以清楚直观的看到每一周药品的销量,我发现每天销量整体相差不大,周五、周六偏于购药高峰。

(2)药品销量前十柱状图

1 color_js = """new echarts.graphic.LinearGradient(0, 1, 0, 0,
 2     [{offset: 0, color: '#FFFFFF'}, {offset: 1, color: '#08519c'}], false)"""
 3 
 4 g2 = df3.groupby('商品名称').sum().sort_values(by='销售数量', ascending=False)
 5 x_data = list(g2.index)[:10]
 6 y_data = g2['销售数量'].values.tolist()[:10]
 7 b2 = (
 8         Bar()
 9         .add_xaxis(x_data)
10         .add_yaxis('',y_data ,itemstyle_opts=opts.ItemStyleOpts(color=JsCode(color_js)))
11         .set_global_opts(title_opts=opts.TitleOpts(title='药品销量前十',pos_top='2%',pos_left = 'center'),
12             legend_opts=opts.LegendOpts(is_show=False),
13             xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-15)),
14             yaxis_opts=opts.AxisOpts(name="销量",name_location='middle',name_gap=50,name_textstyle_opts=opts.TextStyleOpts(font_size=16)))
15 
16     )
17 b2.render('药品销量前十柱状图.html')

外卖平台大数据分析案例 大数据对外卖行业分析_数据_16

  我们在这可以看出:苯磺酸氨氯地平片 (安内真)、开博通、酒石酸美托洛尔片 (倍他乐克) 等治疗高血压、心绞痛药物购买量比较多

 (3)药品销售额前十柱状图

1 color_js = """new echarts.graphic.LinearGradient(0, 1, 0, 0,
 2     [{offset: 0, color: '#FFFFFF'}, {offset: 1, color: '#871F78'}], false)"""
 3 
 4 g3 = df3.groupby('商品名称').sum().sort_values(by='实收金额', ascending=False)
 5 x_data = list(g3.index)[:10]
 6 y_data = g3['实收金额'].values.tolist()[:10]
 7 b3 = (
 8         Bar()
 9         .add_xaxis(x_data)
10         .add_yaxis('',y_data ,itemstyle_opts=opts.ItemStyleOpts(color=JsCode(color_js)))
11         .set_global_opts(title_opts=opts.TitleOpts(title='药品销售额前十',pos_top='2%',pos_left = 'center'),
12             legend_opts=opts.LegendOpts(is_show=False),
13             xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-15)),
14             yaxis_opts=opts.AxisOpts(name="销量",name_location='middle',name_gap=50,name_textstyle_opts=opts.TextStyleOpts(font_size=16)))
15 
16     )
17 b3.render('药品销售额前十柱状图.html')

外卖平台大数据分析案例 大数据对外卖行业分析_数据集_17

 

  我们可以清楚看到药品销售额前十的条形图,我们发现开播通销售额最高,为37671

(4)一周每天订单量

1 # 设置样式
 2 color_js = """new echarts.graphic.LinearGradient(0, 1, 0, 0,
 3     [{offset: 0, color: '#25BEAD'}, {offset: 1, color: '#ed1941'}], false)"""
 4 
 5 area_color_js = (
 6     "new echarts.graphic.LinearGradient(0, 0, 0, 1, "
 7     "[{offset: 0, color: '#25BEAD'}, {offset: 1, color: '#3fbbff0d'}], false)"
 8 )
 9 # 一周每天订单量
10 df_week = df3.groupby(['星期'])['实收金额'].count()
11 week_x_data = df_week.index
12 week_y_data = df_week.values.tolist()
13  
14 line1 = (
15     Line(init_opts=opts.InitOpts(bg_color=JsCode(color_js)))
16     .add_xaxis(xaxis_data=week_x_data)
17     .add_yaxis(
18         series_name="",
19         y_axis=week_y_data,        
20         is_smooth=True,
21         is_symbol_show=True,
22         symbol="circle",
23         symbol_size=6,
24         linestyle_opts=opts.LineStyleOpts(color="#fff"),
25         label_opts=opts.LabelOpts(is_show=True, position="top", color="white"),
26         itemstyle_opts=opts.ItemStyleOpts(
27             color="red", border_color="#fff", border_width=3
28         ),
29         tooltip_opts=opts.TooltipOpts(is_show=False),
30         areastyle_opts=opts.AreaStyleOpts(color=JsCode(area_color_js), opacity=1),
31     )
32     .set_global_opts(
33         title_opts=opts.TitleOpts(
34             title="一周每天订单量",
35             pos_top="2%",
36             pos_left="center",
37             title_textstyle_opts=opts.TextStyleOpts(color="#fff", font_size=16),
38         ),
39         xaxis_opts=opts.AxisOpts(
40             type_="category",
41             boundary_gap=True,
42             axislabel_opts=opts.LabelOpts(margin=30, color="#ffffff63",font_weight =900),
43             axisline_opts=opts.AxisLineOpts(is_show=False),
44             axistick_opts=opts.AxisTickOpts(
45                 is_show=True,
46                 length=25,
47                 linestyle_opts=opts.LineStyleOpts(color="#ffffff1f"),
48             ),
49             splitline_opts=opts.SplitLineOpts(
50                 is_show=True, linestyle_opts=opts.LineStyleOpts(color="#ffffff1f")
51             ),
52         ),
53         yaxis_opts=opts.AxisOpts(
54             type_="value",
55             position="left",
56             axislabel_opts=opts.LabelOpts(margin=20, color="#ffffff63"),
57             axisline_opts=opts.AxisLineOpts(
58                 linestyle_opts=opts.LineStyleOpts(width=2, color="#fff")
59             ),
60             axistick_opts=opts.AxisTickOpts(
61                 is_show=True,
62                 length=15,
63                 linestyle_opts=opts.LineStyleOpts(color="#ffffff1f"),
64             ),
65             splitline_opts=opts.SplitLineOpts(
66                 is_show=True, linestyle_opts=opts.LineStyleOpts(color="#ffffff1f")
67             ),
68         ),
69         legend_opts=opts.LegendOpts(is_show=False),
70     )
71 )
72 line1.render('一周每天订单量分析图.html')

外卖平台大数据分析案例 大数据对外卖行业分析_柱状图_18

  我们通过折线图来分析每周的订单数量

 (5)自然月每天订单数量

1 # 自然月每天订单数量
 2 df3['购药日期'] = pd.to_datetime(df3['购药日期'])
 3 df_day = df3.groupby(df3['购药日期'].dt.day)['星期'].count()
 4 day_x_data = [str(i) for i in list(df_day.index)]
 5 day_y_data = df_day.values.tolist()
 6 line1 = (
 7     Line(init_opts=opts.InitOpts(bg_color=JsCode(color_js)))
 8     .add_xaxis(xaxis_data=day_x_data)
 9     .add_yaxis(
10         series_name="",
11         y_axis=day_y_data,
12         is_smooth=True,
13         is_symbol_show=True,
14         symbol="circle",
15         symbol_size=6,
16         linestyle_opts=opts.LineStyleOpts(color="#fff"),
17         label_opts=opts.LabelOpts(is_show=True, position="top", color="white"),
18         itemstyle_opts=opts.ItemStyleOpts(
19             color="red", border_color="#fff", border_width=3
20         ),
21         tooltip_opts=opts.TooltipOpts(is_show=False),
22         areastyle_opts=opts.AreaStyleOpts(color=JsCode(area_color_js), opacity=1),
23     )
24     .set_global_opts(
25         title_opts=opts.TitleOpts(
26             title="自然月每日订单量",
27             pos_top="5%",
28             pos_left="center",
29             title_textstyle_opts=opts.TextStyleOpts(color="#fff", font_size=16),
30         ),
31         xaxis_opts=opts.AxisOpts(
32             type_="category",
33             boundary_gap=True,
34             axislabel_opts=opts.LabelOpts(margin=30, color="#ffffff63",font_weight =900),
35             axisline_opts=opts.AxisLineOpts(is_show=False),
36             axistick_opts=opts.AxisTickOpts(
37                 is_show=True,
38                 length=25,
39                 linestyle_opts=opts.LineStyleOpts(color="#ffffff1f"),
40             ),
41             splitline_opts=opts.SplitLineOpts(
42                 is_show=True, linestyle_opts=opts.LineStyleOpts(color="#ffffff1f")
43             ),
44         ),
45         yaxis_opts=opts.AxisOpts(
46             type_="value",
47             position="left",
48             axislabel_opts=opts.LabelOpts(margin=20, color="#ffffff63"),
49             axisline_opts=opts.AxisLineOpts(
50                 linestyle_opts=opts.LineStyleOpts(width=2, color="#fff")
51             ),
52             axistick_opts=opts.AxisTickOpts(
53                 is_show=True,
54                 length=15,
55                 linestyle_opts=opts.LineStyleOpts(color="#ffffff1f"),
56             ),
57             splitline_opts=opts.SplitLineOpts(
58                 is_show=True, linestyle_opts=opts.LineStyleOpts(color="#ffffff1f")
59             ),
60         ),
61         legend_opts=opts.LegendOpts(is_show=False),
62     )
63 )
64 line1.render('自然月每天订单数量分析图.html')

外卖平台大数据分析案例 大数据对外卖行业分析_数据集_19

   可以看出:5 日、15 日、25 日是药品销售高峰期,尤其是每月 15 日

(6)每月订单数量

1 # 每月订单数量
 2 df_month = df3.groupby(df3['购药日期'].dt.month)['星期'].count()
 3 day_x_data = [str(i)+'月' for i in list(df_month.index)]
 4 day_y_data = df_month.values.tolist()
 5 line1 = (
 6     Line(init_opts=opts.InitOpts(bg_color=JsCode(color_js)))
 7     .add_xaxis(xaxis_data=day_x_data)
 8     .add_yaxis(
 9         series_name="",
10         y_axis=day_y_data,
11         is_smooth=True,
12         is_symbol_show=True,
13         symbol="circle",
14         symbol_size=6,
15         linestyle_opts=opts.LineStyleOpts(color="#fff"),
16         label_opts=opts.LabelOpts(is_show=True, position="top", color="black"),
17         itemstyle_opts=opts.ItemStyleOpts(
18             color="red", border_color="#fff", border_width=3
19         ),
20         tooltip_opts=opts.TooltipOpts(is_show=False),
21         areastyle_opts=opts.AreaStyleOpts(color=JsCode(area_color_js), opacity=1),
22     )
23     .set_global_opts(
24         title_opts=opts.TitleOpts(
25             title="每月订单量",
26             pos_top="2%",
27             pos_left="center",
28             title_textstyle_opts=opts.TextStyleOpts(color="#fff", font_size=16),
29         ),
30         xaxis_opts=opts.AxisOpts(
31             type_="category",
32             boundary_gap=True,
33             axislabel_opts=opts.LabelOpts(margin=30, color="#ffffff63",font_weight =900),
34             axisline_opts=opts.AxisLineOpts(is_show=False),
35             axistick_opts=opts.AxisTickOpts(
36                 is_show=True,
37                 length=25,
38                 linestyle_opts=opts.LineStyleOpts(color="#ffffff1f"),
39             ),
40             splitline_opts=opts.SplitLineOpts(
41                 is_show=True, linestyle_opts=opts.LineStyleOpts(color="#ffffff1f")
42             ),
43         ),
44         yaxis_opts=opts.AxisOpts(
45             type_="value",
46             position="left",
47             axislabel_opts=opts.LabelOpts(margin=20, color="#ffffff63"),
48             axisline_opts=opts.AxisLineOpts(
49                 linestyle_opts=opts.LineStyleOpts(width=2, color="#fff")
50             ),
51             axistick_opts=opts.AxisTickOpts(
52                 is_show=True,
53                 length=15,
54                 linestyle_opts=opts.LineStyleOpts(color="#ffffff1f"),
55             ),
56             splitline_opts=opts.SplitLineOpts(
57                 is_show=True, linestyle_opts=opts.LineStyleOpts(color="#ffffff1f")
58             ),
59         ),
60         legend_opts=opts.LegendOpts(is_show=False),
61     )
62 )
63 line1.render('每月订单数量分析图.html')

外卖平台大数据分析案例 大数据对外卖行业分析_柱状图_20

  在这里我们可以发现 1 月份和 4 月份药品销售数据较其他几个月更多

(7)五月每日订单量

1 # 五月每日订单量
 2 colors = ['#C9DA36','#9ECB3C','#6DBC49','#37B44E','#3DBA78','#7D3990','#A63F98','#C31C88','#F57A34','#FA8F2F','#CF7B25','#CF7B25','#FF5733','#C70039']
 3 df_day = df3.groupby(df3['购药日期'].dt.day)['星期'].count()
 4 day_x_data = [str(i) for i in list(df_day.index)]
 5 day_y_data = df_day.values.tolist()
 6 times = [x.strftime('%Y-%m-%d') for x in list(pd.date_range('20160501', '20160531'))]
 7 data = [[times[index],day_y_data[index]] for index,item in enumerate( day_y_data)]
 8 Cal = (
 9     Calendar(init_opts=opts.InitOpts(width="800px", height="500px"))
10     .add(
11         series_name="五月每日订单量分布情况",
12         yaxis_data=data,
13         calendar_opts=opts.CalendarOpts(
14              pos_top='20%',
15              pos_left='5%',
16              range_="2016-05",
17              cell_size=40,
18              # 年月日标签样式设置
19              daylabel_opts=opts.CalendarDayLabelOpts(name_map="cn",
20                                                      margin=20,
21                                                      label_font_size=14,
22                                                      label_color='#EB1934', 
23                                                      label_font_weight='bold'
24                                                     ),
25              monthlabel_opts=opts.CalendarMonthLabelOpts(name_map="cn",
26                                                          margin=20,
27                                                          label_font_size=14,
28                                                          label_color='#EB1934', 
29                                                          label_font_weight='bold',
30                                                          is_show=False
31                                                         ),
32              yearlabel_opts=opts.CalendarYearLabelOpts(is_show=False),
33         ),
34         tooltip_opts='{c}',
35     )
36     .set_global_opts(
37         title_opts=opts.TitleOpts(
38             pos_top="2%", 
39             pos_left="center", 
40             title=""
41         ),
42         visualmap_opts=opts.VisualMapOpts(
43             orient="horizontal", 
44             max_=800,
45             pos_bottom='10%',
46             is_piecewise=True,
47             pieces=[{"min": 600},
48                     {"min": 300, "max": 599},
49                     {"min": 200, "max": 299},
50                     {"min": 160, "max": 199},
51                     {"min": 100, "max": 159},
52                     {"max": 99}],
53             range_color=['#ffeda0','#fed976','#fd8d3c','#fc4e2a','#e31a1c','#b10026']
54             
55         ),
56         legend_opts=opts.LegendOpts(is_show=True,
57                                     pos_top='5%',
58                                     item_width = 50,
59                                     item_height = 30,
60                                     textstyle_opts=opts.TextStyleOpts(font_size=16,color='#EB1934'),
61                                     legend_icon ='path://path://M465.621333 469.333333l-97.813333-114.133333a21.333333 21.333333 0 1 1 32.384-27.733333L512 457.856l111.786667-130.432a21.333333 21.333333 0 1 1 32.426666 27.776L558.357333 469.333333h81.493334c11.84 0 21.461333 9.472 21.461333 21.333334 0 11.776-9.6 21.333333-21.482667 21.333333H533.333333v85.333333h106.517334c11.861333 0 21.482667 9.472 21.482666 21.333334 0 11.776-9.6 21.333333-21.482666 21.333333H533.333333v127.850667c0 11.861333-9.472 21.482667-21.333333 21.482666-11.776 0-21.333333-9.578667-21.333333-21.482666V640h-106.517334A21.354667 21.354667 0 0 1 362.666667 618.666667c0-11.776 9.6-21.333333 21.482666-21.333334H490.666667v-85.333333h-106.517334A21.354667 21.354667 0 0 1 362.666667 490.666667c0-11.776 9.6-21.333333 21.482666-21.333334h81.472zM298.666667 127.957333C298.666667 104.405333 317.824 85.333333 341.12 85.333333h341.76C706.304 85.333333 725.333333 104.490667 725.333333 127.957333v42.752A42.645333 42.645333 0 0 1 682.88 213.333333H341.12C317.696 213.333333 298.666667 194.176 298.666667 170.709333V127.957333zM341.333333 170.666667h341.333334V128H341.333333v42.666667z m-105.173333-42.666667v42.666667H170.752L170.666667 895.893333 853.333333 896V170.773333L789.909333 170.666667V128h63.296C876.842667 128 896 147.072 896 170.773333v725.12C896 919.509333 877.013333 938.666667 853.333333 938.666667H170.666667a42.666667 42.666667 0 0 1-42.666667-42.773334V170.773333C128 147.157333 147.114667 128 170.752 128h65.408z'
62                                    ),
63     )
64 )
65 Cal.render('五月每日订单量分析图.html')

外卖平台大数据分析案例 大数据对外卖行业分析_数据集_21

   我们把五月每日订单单独拿出来分析,可以看出:苯磺酸氨氯地平片 (安内真)、开博通、酒石酸美托洛尔片 (倍他乐克) 等治疗高血压、心绞痛药物购买量比较多

(8)药品销售数据词云

1 # 词云
 2 g = df3.groupby('商品名称').sum()
 3 drug_list = []
 4 for idx, value in enumerate(list(g.index)):
 5     drug_list += [value] * list(g['销售数量'].values)[idx]
 6 stylecloud.gen_stylecloud(
 7     text=' '.join(drug_list),
 8     font_path=r'STXINWEI.TTF',
 9     palette='cartocolors.qualitative.Bold_5',# 设置配色方案
10     icon_name='fas fa-lock', # 设置蒙版方案
11 #     background_color='black',
12     max_font_size=200,
13     output_name='药品销量.png',
14     )
15 Image.open("药品销量.png")

外卖平台大数据分析案例 大数据对外卖行业分析_外卖平台大数据分析案例_22

 4.随机森林填补缺失值

  利用随机森林进行填补缺失值的思想:随机森林是进行回归的操作,我们可以把那 些包含缺失值的列当作标签,如果是很多列都有缺失值,那么就要按照每一列的缺失 值的从小到大来填补(因为这样子的话,正确率会更加高一些,因为缺失值少的那个 对特征等的要求更加低一些),然后在将剩下和原本就已经给的标签组成新的特征矩阵 (一般情况下,最开始的标签是不会有缺失值的),在这个特征矩阵里面,将缺失值利用 numpy,pandas 或者 sklearn 的 impleImputer 填补为 0,因为 0 对数据的影响比较小。接着 就是将取出的那个新的标签列,按照有没有缺失值分为 Ytrain 和 Ytest,同样的道理,按 照新标签列有缺失值所在的行的位置,将新的特征矩阵分为 Xtrain 和 Xtest,然后就可 以利用 RandomForestRegressor() 来进行训练和预测,利用 predict 接口来得到最后的 Y, 其实在前面的 Ytest 并没有用处,只是来确定所在的行而已。在这里的 predict 出来的就 是要填补的内容,将它把 Ytest 覆盖就可以了。如果有缺失值的列很多的话,就可以使 用循环,不断的预测就可以了。最后所填补的缺失值的正确率要远比利用 0 填补,均值 填补,中位数填补,最多数填补的高。

1 from sklearn.impute import SimpleImputer
 2 from sklearn.ensemble import RandomForestRegressor
 3 import numpy as np
 4 data_copy = df.copy()
 5 data_copy.drop(data_copy.columns[0], axis=1, inplace=True)
 6 sindex = np.argsort(data_copy.isnull().sum()).values
 7 
 8 # 进行缺失值的填补,利用随机森林进行填补缺失值
 9 for i in sindex :
10     if data_copy.iloc[:,i].isnull().sum() == 0 :
11         continue
12     df = data_copy
13     fillc = df.iloc[:, i]
14     df = df.iloc[:,df.columns!=df.columns[i]]
15 
16 #在下面的是使用了0来对特征矩阵中的缺失值的填补,
17     df_0 = SimpleImputer(missing_values=np.nan
18                         ,strategy="constant"
19                         ,fill_value=0
20                         ).fit_transform(df)
21     Ytrain = fillc[fillc.notnull()]
22     Ytest = fillc[fillc.isnull()]
23     
24     Xtrain = df_0[Ytrain.index,:]
25     Xtest = df_0[Ytest.index,:]
26     
27     rfc = RandomForestRegressor()
28     rfc.fit(Xtrain, Ytrain)
29     Ypredict = rfc.predict(Xtest)
30     
31     data_copy.loc[data_copy.iloc[:,i].isnull(),data_copy.columns[i]] = Ypredict
32 data_copy.isnull().sum()

外卖平台大数据分析案例 大数据对外卖行业分析_柱状图_23

 5完整代码附上

1 import pandas as pd
  2 import stylecloud
  3 from sklearn.impute import SimpleImputer
  4 from sklearn.ensemble import RandomForestRegressor
  5 import numpy as np
  6 from PIL import Image
  7 from collections import Counter
  8 from pyecharts.charts import Bar
  9 from pyecharts.charts import Line
 10 from pyecharts.charts import Calendar
 11 from pyecharts import options as opts
 12 from pyecharts.commons.utils import JsCode
 13 from pyecharts.globals import SymbolType
 14 df = pd.read_excel('电商平台药品销售数据.xlsx')
 15 df.head(10)
 16 from sklearn.impute import SimpleImputer
 17 import numpy as np
 18 # 取出缺失值所在列的数值,sklearn当中特征矩阵必须是二维才能传入 使用reshape(-1,1)升维
 19 sums=df['实收金额'].values.reshape(-1,1)
 20 # 按平均值填充
 21 imp_mean = SimpleImputer(missing_values=np.nan, strategy='mean')
 22 imp_mean=imp_mean.fit_transform(sums)
 23 
 24 df['实收金额']=imp_mean
 25 df
 26 df.info()
 27 df.shape
 28 df.isnull().sum()
 29 df[df.isnull().T.any()]
 30 df1 = df.copy()
 31 df1 = df1.dropna(subset=['购药时间'])
 32 df1[df1.isnull().T.any()]
 33 df1['社保卡号'].fillna('0000', inplace=True)
 34 df1.isnull().sum()
 35 df1['社保卡号'] = df1['社保卡号'].astype(str)
 36 df1['商品编码'] = df1['商品编码'].astype(str)
 37 df1['销售数量'] = df1['销售数量'].astype(int)
 38 df1.info()
 39 df1.head()
 40 df_tmp = pd.read_excel('电商平台药品销售数据.xlsx', converters={'社保卡号':str, '商品编码':str, '销售数量':int})
 41 df_tmp.head()
 42 df2 = df_tmp.copy()
 43 df2 = df2.dropna(subset=['购药时间'])
 44 df2['社保卡号'].fillna('0000', inplace=True)
 45 df2['销售数量'] = df2['销售数量'].astype(int)
 46 df2[['销售数量','应收金额','实收金额']].describe()
 47 df2.loc[(df2['销售数量'] < 0)]
 48 df2['销售数量'] = df2['销售数量'].abs()
 49 df2['应收金额'] = df2['应收金额'].abs()
 50 df2['实收金额'] = df2['实收金额'].abs()
 51 df2.loc[(df2['销售数量'] < 0) | (df2['应收金额'] < 0) | (df2['实收金额'] < 0)].sum()
 52 df3 = df2.copy()
 53 df3[['购药日期', '星期']] = df3['购药时间'].str.split(' ', 2, expand = True)
 54 df3 = df3[['购药日期', '星期','社保卡号','商品编码', '商品名称', '销售数量', '应收金额', '实收金额' ]]
 55 df3
 56 len(df3['购药日期'].unique())
 57 df3.groupby('购药日期').sum()
 58 color_js = """new echarts.graphic.LinearGradient(0, 1, 0, 0,
 59     [{offset: 0, color: '#FFFFFF'}, {offset: 1, color: '#ed1941'}], false)"""
 60 
 61 g1 = df3.groupby('星期').sum()
 62 x_data = list(g1.index)
 63 y_data = g1['销售数量'].values.tolist()
 64 b1 = (
 65         Bar()
 66         .add_xaxis(x_data)
 67         .add_yaxis('',y_data ,itemstyle_opts=opts.ItemStyleOpts(color=JsCode(color_js)))
 68         .set_global_opts(title_opts=opts.TitleOpts(title='一周各天药品销量',pos_top='2%',pos_left = 'center'),
 69             legend_opts=opts.LegendOpts(is_show=False),
 70             xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-15)),
 71             yaxis_opts=opts.AxisOpts(name="销量",name_location='middle',name_gap=50,name_textstyle_opts=opts.TextStyleOpts(font_size=16)))
 72 
 73     )
 74 b1.render('一周各天药品销量柱状图.html')
 75 
 76 color_js = """new echarts.graphic.LinearGradient(0, 1, 0, 0,
 77     [{offset: 0, color: '#FFFFFF'}, {offset: 1, color: '#08519c'}], false)"""
 78 
 79 g2 = df3.groupby('商品名称').sum().sort_values(by='销售数量', ascending=False)
 80 x_data = list(g2.index)[:10]
 81 y_data = g2['销售数量'].values.tolist()[:10]
 82 b2 = (
 83         Bar()
 84         .add_xaxis(x_data)
 85         .add_yaxis('',y_data ,itemstyle_opts=opts.ItemStyleOpts(color=JsCode(color_js)))
 86         .set_global_opts(title_opts=opts.TitleOpts(title='药品销量前十',pos_top='2%',pos_left = 'center'),
 87             legend_opts=opts.LegendOpts(is_show=False),
 88             xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-15)),
 89             yaxis_opts=opts.AxisOpts(name="销量",name_location='middle',name_gap=50,name_textstyle_opts=opts.TextStyleOpts(font_size=16)))
 90 
 91     )
 92 b2.render('药品销量前十柱状图改.html')
 93 
 94 # 设置样式
 95 color_js = """new echarts.graphic.LinearGradient(0, 1, 0, 0,
 96     [{offset: 0, color: '#25BEAD'}, {offset: 1, color: '#ed1941'}], false)"""
 97 
 98 area_color_js = (
 99     "new echarts.graphic.LinearGradient(0, 0, 0, 1, "
100     "[{offset: 0, color: '#25BEAD'}, {offset: 1, color: '#3fbbff0d'}], false)"
101 )
102 # 一周每天订单量
103 df_week = df3.groupby(['星期'])['实收金额'].count()
104 week_x_data = df_week.index
105 week_y_data = df_week.values.tolist()
106  
107 line1 = (
108     Line(init_opts=opts.InitOpts(bg_color=JsCode(color_js)))
109     .add_xaxis(xaxis_data=week_x_data)
110     .add_yaxis(
111         series_name="",
112         y_axis=week_y_data,        
113         is_smooth=True,
114         is_symbol_show=True,
115         symbol="circle",
116         symbol_size=6,
117         linestyle_opts=opts.LineStyleOpts(color="#fff"),
118         label_opts=opts.LabelOpts(is_show=True, position="top", color="white"),
119         itemstyle_opts=opts.ItemStyleOpts(
120             color="red", border_color="#fff", border_width=3
121         ),
122         tooltip_opts=opts.TooltipOpts(is_show=False),
123         areastyle_opts=opts.AreaStyleOpts(color=JsCode(area_color_js), opacity=1),
124     )
125     .set_global_opts(
126         title_opts=opts.TitleOpts(
127             title="一周每天订单量",
128             pos_top="2%",
129             pos_left="center",
130             title_textstyle_opts=opts.TextStyleOpts(color="#fff", font_size=16),
131         ),
132         xaxis_opts=opts.AxisOpts(
133             type_="category",
134             boundary_gap=True,
135             axislabel_opts=opts.LabelOpts(margin=30, color="#ffffff63",font_weight =900),
136             axisline_opts=opts.AxisLineOpts(is_show=False),
137             axistick_opts=opts.AxisTickOpts(
138                 is_show=True,
139                 length=25,
140                 linestyle_opts=opts.LineStyleOpts(color="#ffffff1f"),
141             ),
142             splitline_opts=opts.SplitLineOpts(
143                 is_show=True, linestyle_opts=opts.LineStyleOpts(color="#ffffff1f")
144             ),
145         ),
146         yaxis_opts=opts.AxisOpts(
147             type_="value",
148             position="left",
149             axislabel_opts=opts.LabelOpts(margin=20, color="#ffffff63"),
150             axisline_opts=opts.AxisLineOpts(
151                 linestyle_opts=opts.LineStyleOpts(width=2, color="#fff")
152             ),
153             axistick_opts=opts.AxisTickOpts(
154                 is_show=True,
155                 length=15,
156                 linestyle_opts=opts.LineStyleOpts(color="#ffffff1f"),
157             ),
158             splitline_opts=opts.SplitLineOpts(
159                 is_show=True, linestyle_opts=opts.LineStyleOpts(color="#ffffff1f")
160             ),
161         ),
162         legend_opts=opts.LegendOpts(is_show=False),
163     )
164 )
165 line1.render('一周每天订单量分析图.html')
166 
167 # 每月订单数量
168 df_month = df3.groupby(df3['购药日期'].dt.month)['星期'].count()
169 day_x_data = [str(i)+'月' for i in list(df_month.index)]
170 day_y_data = df_month.values.tolist()
171 line1 = (
172     Line(init_opts=opts.InitOpts(bg_color=JsCode(color_js)))
173     .add_xaxis(xaxis_data=day_x_data)
174     .add_yaxis(
175         series_name="",
176         y_axis=day_y_data,
177         is_smooth=True,
178         is_symbol_show=True,
179         symbol="circle",
180         symbol_size=6,
181         linestyle_opts=opts.LineStyleOpts(color="#fff"),
182         label_opts=opts.LabelOpts(is_show=True, position="top", color="black"),
183         itemstyle_opts=opts.ItemStyleOpts(
184             color="red", border_color="#fff", border_width=3
185         ),
186         tooltip_opts=opts.TooltipOpts(is_show=False),
187         areastyle_opts=opts.AreaStyleOpts(color=JsCode(area_color_js), opacity=1),
188     )
189     .set_global_opts(
190         title_opts=opts.TitleOpts(
191             title="每月订单量",
192             pos_top="2%",
193             pos_left="center",
194             title_textstyle_opts=opts.TextStyleOpts(color="#fff", font_size=16),
195         ),
196         xaxis_opts=opts.AxisOpts(
197             type_="category",
198             boundary_gap=True,
199             axislabel_opts=opts.LabelOpts(margin=30, color="#ffffff63",font_weight =900),
200             axisline_opts=opts.AxisLineOpts(is_show=False),
201             axistick_opts=opts.AxisTickOpts(
202                 is_show=True,
203                 length=25,
204                 linestyle_opts=opts.LineStyleOpts(color="#ffffff1f"),
205             ),
206             splitline_opts=opts.SplitLineOpts(
207                 is_show=True, linestyle_opts=opts.LineStyleOpts(color="#ffffff1f")
208             ),
209         ),
210         yaxis_opts=opts.AxisOpts(
211             type_="value",
212             position="left",
213             axislabel_opts=opts.LabelOpts(margin=20, color="#ffffff63"),
214             axisline_opts=opts.AxisLineOpts(
215                 linestyle_opts=opts.LineStyleOpts(width=2, color="#fff")
216             ),
217             axistick_opts=opts.AxisTickOpts(
218                 is_show=True,
219                 length=15,
220                 linestyle_opts=opts.LineStyleOpts(color="#ffffff1f"),
221             ),
222             splitline_opts=opts.SplitLineOpts(
223                 is_show=True, linestyle_opts=opts.LineStyleOpts(color="#ffffff1f")
224             ),
225         ),
226         legend_opts=opts.LegendOpts(is_show=False),
227     )
228 )
229 line1.render('每月订单数量分析图.html')
230 # 五月每日订单量
231 colors = ['#C9DA36','#9ECB3C','#6DBC49','#37B44E','#3DBA78','#7D3990','#A63F98','#C31C88','#F57A34','#FA8F2F','#CF7B25','#CF7B25','#FF5733','#C70039']
232 df_day = df3.groupby(df3['购药日期'].dt.day)['星期'].count()
233 day_x_data = [str(i) for i in list(df_day.index)]
234 day_y_data = df_day.values.tolist()
235 times = [x.strftime('%Y-%m-%d') for x in list(pd.date_range('20160501', '20160531'))]
236 data = [[times[index],day_y_data[index]] for index,item in enumerate( day_y_data)]
237 Cal = (
238     Calendar(init_opts=opts.InitOpts(width="800px", height="500px"))
239     .add(
240         series_name="五月每日订单量分布情况",
241         yaxis_data=data,
242         calendar_opts=opts.CalendarOpts(
243              pos_top='20%',
244              pos_left='5%',
245              range_="2016-05",
246              cell_size=40,
247              # 年月日标签样式设置
248              daylabel_opts=opts.CalendarDayLabelOpts(name_map="cn",
249                                                      margin=20,
250                                                      label_font_size=14,
251                                                      label_color='#EB1934', 
252                                                      label_font_weight='bold'
253                                                     ),
254              monthlabel_opts=opts.CalendarMonthLabelOpts(name_map="cn",
255                                                          margin=20,
256                                                          label_font_size=14,
257                                                          label_color='#EB1934', 
258                                                          label_font_weight='bold',
259                                                          is_show=False
260                                                         ),
261              yearlabel_opts=opts.CalendarYearLabelOpts(is_show=False),
262         ),
263         tooltip_opts='{c}',
264     )
265     .set_global_opts(
266         title_opts=opts.TitleOpts(
267             pos_top="2%", 
268             pos_left="center", 
269             title=""
270         ),
271         visualmap_opts=opts.VisualMapOpts(
272             orient="horizontal", 
273             max_=800,
274             pos_bottom='10%',
275             is_piecewise=True,
276             pieces=[{"min": 600},
277                     {"min": 300, "max": 599},
278                     {"min": 200, "max": 299},
279                     {"min": 160, "max": 199},
280                     {"min": 100, "max": 159},
281                     {"max": 99}],
282             range_color=['#ffeda0','#fed976','#fd8d3c','#fc4e2a','#e31a1c','#b10026']
283             
284         ),
285         legend_opts=opts.LegendOpts(is_show=True,
286                                     pos_top='5%',
287                                     item_width = 50,
288                                     item_height = 30,
289                                     textstyle_opts=opts.TextStyleOpts(font_size=16,color='#EB1934'),
290                                     legend_icon ='path://path://M465.621333 469.333333l-97.813333-114.133333a21.333333 21.333333 0 1 1 32.384-27.733333L512 457.856l111.786667-130.432a21.333333 21.333333 0 1 1 32.426666 27.776L558.357333 469.333333h81.493334c11.84 0 21.461333 9.472 21.461333 21.333334 0 11.776-9.6 21.333333-21.482667 21.333333H533.333333v85.333333h106.517334c11.861333 0 21.482667 9.472 21.482666 21.333334 0 11.776-9.6 21.333333-21.482666 21.333333H533.333333v127.850667c0 11.861333-9.472 21.482667-21.333333 21.482666-11.776 0-21.333333-9.578667-21.333333-21.482666V640h-106.517334A21.354667 21.354667 0 0 1 362.666667 618.666667c0-11.776 9.6-21.333333 21.482666-21.333334H490.666667v-85.333333h-106.517334A21.354667 21.354667 0 0 1 362.666667 490.666667c0-11.776 9.6-21.333333 21.482666-21.333334h81.472zM298.666667 127.957333C298.666667 104.405333 317.824 85.333333 341.12 85.333333h341.76C706.304 85.333333 725.333333 104.490667 725.333333 127.957333v42.752A42.645333 42.645333 0 0 1 682.88 213.333333H341.12C317.696 213.333333 298.666667 194.176 298.666667 170.709333V127.957333zM341.333333 170.666667h341.333334V128H341.333333v42.666667z m-105.173333-42.666667v42.666667H170.752L170.666667 895.893333 853.333333 896V170.773333L789.909333 170.666667V128h63.296C876.842667 128 896 147.072 896 170.773333v725.12C896 919.509333 877.013333 938.666667 853.333333 938.666667H170.666667a42.666667 42.666667 0 0 1-42.666667-42.773334V170.773333C128 147.157333 147.114667 128 170.752 128h65.408z'
291                                    ),
292     )
293 )
294 Cal.render('五月每日订单量分析图.html')
295 
296 # 词云
297 g = df3.groupby('商品名称').sum()
298 drug_list = []
299 for idx, value in enumerate(list(g.index)):
300     drug_list += [value] * list(g['销售数量'].values)[idx]
301 stylecloud.gen_stylecloud(
302     text=' '.join(drug_list),
303     font_path=r'STXINWEI.TTF',
304     palette='cartocolors.qualitative.Bold_5',# 设置配色方案
305     icon_name='fas fa-lock', # 设置蒙版方案
306 #     background_color='black',
307     max_font_size=200,
308     output_name='药品销量.png',
309     )
310 Image.open("药品销量.png")
311 
312 data_copy = df.copy()
313 data_copy.drop(data_copy.columns[0], axis=1, inplace=True)
314 sindex = np.argsort(data_copy.isnull().sum()).values
315 # 进行缺失值的填补,利用随机森林进行填补缺失值
316 for i in sindex :
317     if data_copy.iloc[:,i].isnull().sum() == 0 :
318         continue
319     df = data_copy
320     fillc = df.iloc[:, i]
321     df = df.iloc[:,df.columns!=df.columns[i]]
322 
323 #在下面的是使用了0来对特征矩阵中的缺失值的填补,
324     df_0 = SimpleImputer(missing_values=np.nan
325                         ,strategy="constant"
326                         ,fill_value=0
327                         ).fit_transform(df)
328     Ytrain = fillc[fillc.notnull()]
329     Ytest = fillc[fillc.isnull()]
330     
331     Xtrain = df_0[Ytrain.index,:]
332     Xtest = df_0[Ytest.index,:]
333     
334     rfc = RandomForestRegressor()
335     rfc.fit(Xtrain, Ytrain)
336     Ypredict = rfc.predict(Xtest)
337     
338     data_copy.loc[data_copy.iloc[:,i].isnull(),data_copy.columns[i]] = Ypredict
339 data_copy.isnull().sum()

四、总结

  在进行药品销售数量的大数据分析时,我通过对数据的分析和挖掘,得出了以下有益的结论:通过对销售数据的时间序列分析,我发现药品销售数量存在季节性波动,在春季和秋季销售数量通常较高,在夏季和冬季销售数量通常较低。在完成此设计过程中,我得到了许多收获。首先,我学会了如何进行大数据分析,包括如何清洗数据、如何使用数据分析工具进行数据分析和可视化。其次,我还学会了如何根据分析结果得出有益的结论并提出建议。在未来的工作中,我建议对数据进行更深入的分析,例如通过进行回归分析来更准确地预测药品销售数量的变化趋势,并进一步优化药品销售策略。此外,我还建议对数据进行实时更新,以便更好地反映市场变化并进行及时调整。