开源图书《Python完全自学教程》12.5数据分析

2022-12-09 20:25:58 浏览数 (1)

12.5. 数据分析

随着数据科学的发展,数据分析或者数据挖掘已经越来越受到各种业务的重视,比如商业、生产等领域,各种决策也更多地依靠数据分析的结果,逐渐减少个人经验和“拍脑门”“抖机灵”等在决策中的成分。

如果要分析小量的结构化数据,用类似于电子表格的工具软件就能完成。但是,数据量如果很大(所谓“大数据”,是一个相对的模糊概念),还可能遇到非结构化的数据,再使用类电子表格的工具软件或许不太适合,这时候编程语言就有用武之地了。

下面以一个开网店的案例,说明数据分析对商业决策的支持作用。

张三发现网上购物已经成为了人们的习惯,就打算开个小网店——“梦想还是要有的,万一实现了呢”。他笃信广为流传的“犹太人赚钱法则”:“要想赚钱,就必须为女性服务”——此结论可用数据进行证实,有兴趣的读者不妨尝试。在“家庭会议上”,“大领导”支持了他的理想,还为网店所销售的商品做出了重要指示:专卖文胸。但是,卖什么类型的,什么颜色的,尺码多大的,就需要张三自己来决定了。张三就是一名数据分析师,他深知不能凭直觉来——更不能根据影视作品中看到的做出决策,必须要“依据数据决策”。于是张三根据“家庭会议”精神开始了有条不紊的数据分析工作。

首先,到某电商平台上,利用网络爬虫技术(数据工程师如果会这项技术,如虎添翼),获得了一些文胸的评论数据,准备通过这些数据分析出消费者的消费取向。本节的重点是数据分析,网络爬虫技术留给读者研究。

下面使用 Pandas 开始研究这些数据。Pandas 是数据科学中常用的第三方库,在 12.4.2 节已经安装,更多关于 Pandas 的使用方法,推荐参阅拙作《跟老齐学 Python:数据分析》(电子工业出版社出版)。

代码语言:javascript复制
[1]: import pandas as pd
     datas = pd.read_csv("./data/bra.csv")
     datas.head()
[1]:           creationTime productColor productSize
     0 2016-06-08 17:17:00      22咖啡色         75C
     1 2017-04-07 19:34:25      22咖啡色         80B
     2 2016-06-18 19:44:56       02粉色          80C
     3 2017-08-03 20:39:18      22咖啡色         80B
     4 2016-07-06 14:02:08      22咖啡色         75B

将获取到的数据保存在了 bra.csv 文件中,读取其中的前几条,先对数据有直观认识。接下来要认真地查看特征 'productColor' 中的数据。

代码语言:javascript复制
[2]: datas['productColor'].unique()
[2]: array(['22咖啡色', '02粉色', '071蓝色', '071黑色', '071肤色', '0993无痕肤色', 
            '0993无痕黑色', '071红色', '0993无痕酒红色', 'h03无痕蓝灰', '蓝灰色', 
     # .... (省略部分内容)
            '黑色 单件', '蓝色 单件', '浅紫', '紫色套装(其他颜色备注)', 
            '粉色套装(含内裤)', '虾粉'], dtype=object)

这么多颜色,对于数据分析来说,应该进行“数据清洗”——这是数据科学中最耗费时间和精力的工作(参阅拙作《数据准备和特征工程》,电子工业出版社出版)。并且,对业务越熟悉,数据清洗得就越“干净”,且符合分析所需。此处为了突出“数据分析”,暂将重要的“数据清洗”过程省略,直接显示清洗后的数据。

代码语言:javascript复制
[3]: cleaned_datas = pd.read_csv("./data/cleaned_data.csv", index_col=0)
     cleaned_datas.head()
[3]:           creationTime productColor productSize color
     0 2016-06-08 17:17:00     22咖啡色           75C   棕色
     1 2017-04-07 19:34:25     22咖啡色           80B   棕色
     2 2016-06-18 19:44:56       02粉色          80C  粉色
     3 2017-08-03 20:39:18      22咖啡色         80B   棕色
     4 2016-07-06 14:02:08      22咖啡色         75B   棕色

所显示的 'color' 列是清洗之后的数据,后续分析所用数据即为此列。

为了知道样本的颜色分布,要绘制柱形图,反映出 color 特征下不同值的样本数量。

绘图的工具 Matplotlib 默认不支持中文(此第三方库已经在 12.4.2 节安装),要先把这个小问题解决了。

代码语言:javascript复制
[4]: from matplotlib.font_manager import FontManager
     import subprocess

     mpl_fonts = set(f.name for f in FontManager().ttflist)

     print('all font list get from matplotlib.font_manager:')
     for f in sorted(mpl_fonts):
         print('t'   f)
[4]: all font list get from matplotlib.font_manager:
            .Aqua Kana
           .Arabic UI Display
           .Arabic UI Text
            ... #(省略部分输出)
            Songti SC
            ... #(省略部分输出)

用代码块 [4] 可以显示出本地计算机系统所支持的字体,可能很多,从中细心地找出中文字体。然后将该字体用于下面的代码块中(本例中使用的是 Songti SC 字体,读者可以根据自己的情况设置)。

代码语言:javascript复制
[5]: import matplotlib.pyplot as plt
     import matplotlib
     matplotlib.rc("font",family='Songti SC')     # 设置字体

     color_count = cleaned_datas.groupby('color').count()    # 分组统计
     numbers = color_count['productColor']
     labels = numbers.index
     position = range(len(labels))

     plt.bar(x=position, height=numbers.values, 
             width=0.6, tick_label=labels)           # 绘制柱形图
     plt.xticks(position, labels)

输出图示:

从输出结果中可以一目了然知道当前数据集中,哪些颜色的样本较少——购买者少,哪些颜色的样本较多——购买者多。

如此,张三就知道网店应该销售什么颜色的文胸了。

接下来,就要解决大小问题。路数与前面类似,先看看原始数据。

代码语言:javascript复制
[6]: datas['productSize'].str.upper().unique()
[6]: array(['75C', '80B', '80C', '75B', '70C', '85B', '70B', '85C', 
            '75C/34C','80B/36B', '85C/38C', '85A/38A', '85B/38B', '80A/36A', 
            '70A/32A','80C/36C', '75B/34B', '75A/34A', '70B/32B', '70C/32C', 
            'B80','B75', 'C80', '170/82/XL', 'C75', '160/70/M', 'B70', 
            '165/76/L','C70', nan, '90C/40C', '90B/40B', '85D/38D', 
            '85B (内裤)套装','85E/38E', '80D/36D', '90D/40D', '80E/36E', 
            '75E/34E', '90E/40E','75D/34D', '95C', '95E', '85E (内裤)套装', 
            '95D', '75B (内裤)套装','75B=34B', '80B=36B', '80C=36C', '90D=40D', 
            '85B=38B', '80A=36A','85C=38C', '90B=40B', '75A=34A', '90C=40C', 
            '85A=38A', '75C=34C','85/38C', '75B/34', '85B/38', '80B/36', 
            '70B/32', 'A75', 'A80', 'A70', '75A', '80A', '70A', '85A', 
            '70A=32A', '70B=32B', 'A85', 'C85', 'B85', '90C', '40/90A=XL码', 
            '34/75D=L码', '32/70B=S码', '36/80B=L码', '38/85A=L码', 
            '38/85C=XL码', '36/80C=L码', '38/85B=XL码', '38/85D=XL码', 
            '34/75B=M码', '34/75C=M码', '34/75A=S码', '40/90C=XL码', 
            '36/80A=M码', '75B=34B ', '34/75AB中厚2CM', '75B=34AB', 
            '80B=36AB', '75B  ', '38/85AB中厚2CM', '34/75C薄款0.8CM', '80B ', 
            '85B=38AB  ', '85B=38AB', '70B=32AB', '80A=36A厚杯', '70A=32A厚杯', 
            '75A=34A厚杯', '75B=34B(粉色预发货17号)', '75B=34B粉色预计4天发', 
            '75B=34B(粉色预发货20号)', '75B=34B(粉色预发货26号)', '34B/75B', 
            '34/75B', '40C/90C', '32B/70B', '34A/75A', '36C/80C', '34C/75C', 
            '36B/80B', '34B=75B', '36A/80A', '32A/70A', '38B/85B', 
            '38A/85A'], dtype=object)

也很复杂——超出了张三的原有认识。还要继续进行数据清洗,在有关“专家”的指导下,经过如下一番操作(为了简化并好理解,“专家”特别建议将大小进行简化,用 A-E 表示),将数据清洗完毕。

代码语言:javascript复制
[7]: size_1 = datas['productSize'].str.upper().str.findall('[a-zA-Z]').str[0]
     size_2 = size_1.str.replace('M', 'B')
     size_3 = size_2.str.replace('L', 'C')
     size_4 = size_3.str.replace('XC', 'C')
     size_5 = size_4.str.replace('AB', 'B')
     size_6 = size_5.str.replace('X', 'D')
     datas['size'] = size_6
     datas.head()
[7]:           creationTime productColor productSize size
     0 2016-06-08 17:17:00     22咖啡色          75C    C
     1 2017-04-07 19:34:25     22咖啡色          80B    B
     2 2016-06-18 19:44:56       02粉色          80C    C
     3 2017-08-03 20:39:18     22咖啡色          80B    B
     4 2016-07-06 14:02:08     22咖啡色          75B    B

新增的 size 列就是清洗的结果,下面对该特征进行分组统计,然后绘制饼图,显示不同尺寸的文胸的分布。

代码语言:javascript复制
[8]: size_count = datas.groupby('size').count()

     labels = ["A", "B", "C", "D", "E"]
     fig, ax = plt.subplots()
     explode = (0, 0.1, 0, 0, 0)
     ax.pie(size_count['productColor'], explode=explode, 
            labels=labels, autopct="%1.1f%%", 
            radius=1.2, startangle=0)
     ax.set(aspect='equal')

输出图示:

通过此图,也知道应该销售多大尺码的了。

诚然,上述数据对于网店的运营决策还比较单薄,这里仅仅以此为例,说明数据分析的作用。读者如果有兴趣深入研究,不妨参考拙作《跟老齐学 Python:数据分析》的有关内容。

自学建议 1997年11月,统计学家吴建福提出将统计学重命名为“数据科学”,同时统计学家应称为“数据科学家”。现在一般认为数据科学(data science)综合了多个领域的理论和技术,包括但不限于统计分析、数据挖掘、机器学习等,其目标是从数据中提取出有价值的部分,应用于相关的数据产品之中。 在我的个人网站(www.itdiffer.com)有关于数据科学的学习内容和职业发展的讲座资料,有兴趣的读者可以参考。

0 人点赞