当前位置:   article > 正文

SparkSQL案例-图书信息分析_基于sparkstraming的图书评分数据分析系统

基于sparkstraming的图书评分数据分析系统


SparkSQL是Spark为处理结构化数据提供的高级组件,本文将使用SparkSQL完成图书信息统计,示例代码将分别以DSL和SQL两种风格进行讲解,并结合Matplotlib和Pandas对结果进行可视化呈现。

文末提供数据和源代码的网盘资源。

实验环境

  • ubuntu1804
  • pyspark2.4.7
  • JupyterLab
  • Anconda3

实验环境可参考:https://blog.csdn.net/tangyi2008/article/details/123109198

JupyterLab使用可参考:https://blog.csdn.net/tangyi2008/article/details/123761210

数据集介绍

  • 数据文件 books.txt

    数据片段

    序号,书名,评分,价格,出版社,url
    5173,動力取向精神醫學--臨床應用與實務,10.0 ,1200元,心灵工坊,https://book.douban.com/subject/6053667/
    9929,水彩绘森活,10.0 ,29.8,人民邮电出版社,https://book.douban.com/subject/26115807/
    10124,殷周金文集成(修订增补本共8册)(精),10.0 ,2400.00元,中华书局,https://book.douban.com/subject/2235855/
    16628,纸雕游戏大书,10.0 ,99.00元,重庆出版集团,https://book.douban.com/subject/26673804/
    19103,Michelangelo,10.0 ,$200.00 ,Taschen,https://book.douban.com/subject/2342660/
    20063,一支笔的快乐涂鸦2,10.0 ,29.8,人民邮电出版社,https://book.douban.com/subject/26280062/
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 数据包含6个字段,每个字段用逗号,分隔,是一个标准的CSV文件
    • 数据中包含中文字符,读取时要考虑文件的编码
    • 数据第一行为中文的字段名

问题描述

  • 查询书名包含“程序”的书
    • 统计其数量
  • 查询评分大于9的图书
  • 统计各个出版社的图书量
    • 要求按从大到小的顺序排序
  • 可视化出版社的图书量Top10
  • 统计各出版社所出版书籍的平均评分
    • 只统计评论数在200以上的出版社
    • 按平均分从高到低排序
    • 可视化平均评分Top10

实验步骤

0. 准备工作

  • 在home目录下创建目录book

    mkdir ~/book
    
    • 1
  • 将数据文件上传至目录~/book

  • 使用如下shell命令查看文件编码

    file ~/book/book.txt
    
    • 1

    可看到如下内容,可知文件编码为UTF-8

    book.txt: UTF-8 Unicode text, with CRLF line terminators
    
    • 1

    也可以用vim打开文件vim book.txt,在命令行模式下输入:set fileencoding查看编码

  • 启动JupyterLab

    cd ~/book
    jupyter lab
    
    • 1
    • 2

    在JupyterLab中新建Notebook

    在这里插入图片描述

1. 观察数据

1) 创建SparkSession

from pyspark.sql import SparkSession
spark = SparkSession.builder.master('local').appName('sparksql-book').getOrCreate()
  • 1
  • 2

2) 读取文件并观察数据

从刚才的文件片段可知,要读取该文件,可以指定DataFrame Reader的读取格式为csv;其次,字段名都为中文,不方便写代码所以在导入数据时指定了schema信息。

  • schema由许多字段构成的 StructType,这些字段即为 StructField,它具有名称、类型、布尔标志(该标志指定该列是否可以包含缺失值或空值),并且用户可指定与该列关联的元数据(metadata)。
from pyspark.sql.types import *
schema = StructType([
    StructField('id', StringType(), False),
    StructField('name', StringType(), True),
    StructField('rate', FloatType(), True),
    StructField('price', StringType(), True),
    StructField('publish', StringType(), True),
    StructField('url', StringType(), True),
])
books = spark.read.csv('file:///home/xiaobai/book/book.txt', header=True, schema=schema)
books.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
+-----+-----------------------------------+----+---------+------------------+--------------------+
|   id|                               name|rate|    price|           publish|                 url|
+-----+-----------------------------------+----+---------+------------------+--------------------+
| 5173|   動力取向精神醫學--臨床應用與實務|10.0|   1200元|          心灵工坊|https://book.doub...|
| 9929|                         水彩绘森活|10.0|     29.8|    人民邮电出版社|https://book.doub...|
|10124|  殷周金文集成(修订增补本共8册)(精)|10.0|2400.00元|          中华书局|https://book.doub...|
|16628|                       纸雕游戏大书|10.0|  99.00元|      重庆出版集团|https://book.doub...|
|19103|                       Michelangelo|10.0| $200.00 |           Taschen|https://book.doub...|
|20063|                  一支笔的快乐涂鸦2|10.0|     29.8|    人民邮电出版社|https://book.doub...|
|32781|                         亲亲宝贝装|10.0|  28.00元|江西科学技术出版社|https://book.doub...|
|32879|                     Photoshop7解像|10.0|  68.00元|        海洋出版社|https://book.doub...|
|45687|                   戚蓼生序本石头记|10.0| 350.00元|    人民文学出版社|https://book.doub...|
|52504|                      宇宙兄弟(7)|10.0|   JPY580|            講談社|https://book.doub...|
|52505|                      宇宙兄弟(8)|10.0|   JPY580|            講談社|https://book.doub...|
|  573|            TCP\IP详解(卷1英文版)| 9.9|       45|    机械工业出版社|https://book.doub...|
|  589|计算机程序设计艺术卷1:基本算法(...| 9.9| 119.00元|    人民邮电出版社|https://book.doub...|
| 5522|         微积分和数学分析引论-第1卷| 9.9|  79.00元|  世界图书出版公司|https://book.doub...|
| 5547|               PrinciplesofNeura...| 9.9| $103.41 |McGraw-HillMedical|https://book.doub...|
| 7443|           奈特人体神经解剖彩色图谱| 9.9| 138.00元|    人民卫生出版社|https://book.doub...|
| 8703|                 数学、科学和认识论| 9.9|  32.00元|        商务印书馆|https://book.doub...|
| 9924|                       零基础学素描| 9.9|     20元|    人民邮电出版社|https://book.doub...|
| 9926|     黑白花意3:300例超写实的花之绘| 9.9|  29.80元|    人民邮电出版社|https://book.doub...|
| 9927|         黑白画意:经典植物手绘教程| 9.9|  29.80元|    人民邮电出版社|https://book.doub...|
+-----+-----------------------------------+----+---------+------------------+--------------------+
only showing top 20 rows
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 查看下books的类型:type(books)
  • 通过RDD的方式查看前5个元素:books.take(5)
  • 查看books的元信息:books.schema

2. 将DataFrame注册为View

SparkSQL提供了两种操作方式

  • DSL
  • SQL

本案例将分别使用两种方式演示,为了使用SQL方式,需要先将对应的DataFrame注册为View

books.createOrReplaceTempView('books')
  • 1

过时的方式为registerTempTable,在Spark2.0后弃用

DataFrame提供了四种方式注册为View,

  • df.createTempView

  • df.createOrReplaceTempView

  • df.createGlobalTempView

  • df.createOrReplaceGlobalTempView

上面四种方法的区别与联系:

  • 从使用范围方面,可分为带global和不带两种,其中带global是当前spark application中可用,不带时只能被当前spark session使用

  • 从创建的角度看,可分为带replace和不带两种,当创建视图时,如果目标视图已经存在,带replace的函数会覆盖掉原来的,否则将报错

3. 查询书名包含“程序”的书

  • DSL

    查看包含“程序”的书

    books.filter('name LIKE "%程序%" ').show()
    
    • 1
    +----+------------------------------------+----+--------+--------------+--------------------+
    |  id|                                name|rate|   price|       publish|                 url|
    +----+------------------------------------+----+--------+--------------+--------------------+
    | 589| 计算机程序设计艺术卷1:基本算法(...| 9.9|119.00元|人民邮电出版社|https://book.doub...|
    | 343|         计算机程序设计艺术(第3卷)| 9.8| 98.00元|国防工业出版社|https://book.doub...|
    | 173|计算机程序设计艺术第2卷半数值算法...| 9.7|      83|清华大学出版社|https://book.doub...|
    | 198|                       C程序设计语言| 9.7| 23.00元|清华大学出版社|https://book.doub...|
    | 634|                       C程序设计语言| 9.7| 35.00元|机械工业出版社|https://book.doub...|
    | 342|                  计算机程序设计艺术| 9.6| 45.00元|机械工业出版社|https://book.doub...|
    |  10|              计算机程序的构造和解释| 9.5| 45.00元|机械工业出版社|https://book.doub...|
    | 328|  C++程序设计语言(特别版)(英文...| 9.5|      55|高等教育出版社|https://book.doub...|
    | 344|         计算机程序设计艺术(第1卷)| 9.5| 98.00元|国防工业出版社|https://book.doub...|
    |  25|                       C程序设计语言| 9.4| 30.00元|机械工业出版社|https://book.doub...|
    | 175|         计算机程序设计艺术(第2卷)| 9.4| 98.00元|国防工业出版社|https://book.doub...|
    | 556|       深入Linux设备驱动程序内核机制| 9.4| 98.00元|电子工业出版社|https://book.doub...|
    |  83|         计算机程序设计艺术(第1卷)| 9.3| 80.00元|清华大学出版社|https://book.doub...|
    | 282|         JavaScript高级程序设计(...| 9.3| 99.00元|人民邮电出版社|https://book.doub...|
    | 538|        JavaScript高级程序设计:第2版| 9.3| 89.00元|人民邮电出版社|https://book.doub...|
    | 307|                        程序设计实践| 9.2|      22|机械工业出版社|https://book.doub...|
    |1025|                     Windows程序设计| 9.2|129.00元|北京大学出版社|https://book.doub...|
    |1090|                        程序设计实践| 9.2| 59.00元|机械工业出版社|https://book.doub...|
    |2927|                       C语言程序设计| 9.2| 79.00元|人民邮电出版社|https://book.doub...|
    |  36|                        程序设计实践| 9.1| 20.00元|机械工业出版社|https://book.doub...|
    +----+------------------------------------+----+--------+--------------+--------------------+
    only showing top 20 rows
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    统计其数量

    books.filter('name LIKE "%程序%" ').count()
    
    • 1
    104
    
    • 1
  • SQL

    查看包含“程序”的书

    spark.sql('select * from books where name LIKE "%程序%"').show()
    
    • 1

    统计其数量

    spark.sql('select count(*) from books where name LIKE "%程序%"').show()
    
    • 1

show(n=20, truncate=True, vertical=False)默认打印前20条数,可传参控制输出行数、内容是否截断以及打印方式

4. 查询评分大于9的图书

  • DSL

    from pyspark.sql.functions import col
    books.filter(col('rate') > 9).show()
    
    • 1
    • 2
    +-----+-----------------------------------+----+---------+------------------+--------------------+
    |   id|                               name|rate|    price|           publish|                 url|
    +-----+-----------------------------------+----+---------+------------------+--------------------+
    | 5173|   動力取向精神醫學--臨床應用與實務|10.0|   1200元|          心灵工坊|https://book.doub...|
    | 9929|                         水彩绘森活|10.0|     29.8|    人民邮电出版社|https://book.doub...|
    |10124|  殷周金文集成(修订增补本共8册)(精)|10.0|2400.00元|          中华书局|https://book.doub...|
    |16628|                       纸雕游戏大书|10.0|  99.00元|      重庆出版集团|https://book.doub...|
    |19103|                       Michelangelo|10.0| $200.00 |           Taschen|https://book.doub...|
    |20063|                  一支笔的快乐涂鸦2|10.0|     29.8|    人民邮电出版社|https://book.doub...|
    |32781|                         亲亲宝贝装|10.0|  28.00元|江西科学技术出版社|https://book.doub...|
    |32879|                     Photoshop7解像|10.0|  68.00元|        海洋出版社|https://book.doub...|
    |45687|                   戚蓼生序本石头记|10.0| 350.00元|    人民文学出版社|https://book.doub...|
    |52504|                      宇宙兄弟(7)|10.0|   JPY580|            講談社|https://book.doub...|
    |52505|                      宇宙兄弟(8)|10.0|   JPY580|            講談社|https://book.doub...|
    |  573|            TCP\IP详解(卷1英文版)| 9.9|       45|    机械工业出版社|https://book.doub...|
    |  589|计算机程序设计艺术卷1:基本算法(...| 9.9| 119.00元|    人民邮电出版社|https://book.doub...|
    | 5522|         微积分和数学分析引论-第1卷| 9.9|  79.00元|  世界图书出版公司|https://book.doub...|
    | 5547|               PrinciplesofNeura...| 9.9| $103.41 |McGraw-HillMedical|https://book.doub...|
    | 7443|           奈特人体神经解剖彩色图谱| 9.9| 138.00元|    人民卫生出版社|https://book.doub...|
    | 8703|                 数学、科学和认识论| 9.9|  32.00元|        商务印书馆|https://book.doub...|
    | 9924|                       零基础学素描| 9.9|     20元|    人民邮电出版社|https://book.doub...|
    | 9926|     黑白花意3:300例超写实的花之绘| 9.9|  29.80元|    人民邮电出版社|https://book.doub...|
    | 9927|         黑白画意:经典植物手绘教程| 9.9|  29.80元|    人民邮电出版社|https://book.doub...|
    +-----+-----------------------------------+----+---------+------------------+--------------------+
    only showing top 20 rows
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    表示列rate的方式有多种

    • col('rate') #需要导入col函数
    • books.rate #这种写法要注意列名要不与方法名重名,比如有一列叫count,当你使用books.count表示列时就会报错,因为它表示的是一个方法
    • books['rate']
  • SQL

    spark.sql('select * from books where rate > 9').show()
    
    • 1

5. 统计各个出版社的图书量

  • DSL

    books.groupby('publish').count().sort(col('count').desc()).show()
    
    • 1

    或者

    books.groupby('publish').count().sort('count', ascending=False).show()
    
    • 1
    +----------------------+-----+
    |               publish|count|
    +----------------------+-----+
    |        人民文学出版社| 1437|
    |        上海译文出版社| 1426|
    |              中华书局| 1278|
    |            东立出版社| 1223|
    |生活·读书·新知三联书店| 1105|
    |        北京大学出版社|  948|
    |            译林出版社|  934|
    |            商务印书馆|  917|
    |        上海人民出版社|  829|
    |    广西师范大学出版社|  726|
    |    中国人民大学出版社|  641|
    |        人民邮电出版社|  599|
    |        上海古籍出版社|  590|
    |          南海出版公司|  575|
    |            尖端出版社|  557|
    |            中信出版社|  537|
    |        机械工业出版社|  519|
    |            新星出版社|  511|
    |                集英社|  465|
    |                講談社|  426|
    +----------------------+-----+
    only showing top 20 rows
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
  • SQL

    spark.sql('select publish, count(1) as count from books group by publish order by count desc' ).show()
    
    • 1

6. 可视化出版社的图书量Top10

1)解决中文显示问题

如果不在乎中文显示乱码或者嫌麻烦,跳过此步骤
方法一

import matplotlib.pyplot as plt
# 用来正常显示中文标签,如果是Linux,可以使用命令`fc-list :lang=zh`查看支持中文的字体
plt.rcParams['font.sans-serif'] = ['WenQuanYi Micro Hei']
plt.rcParams["axes.unicode_minus"] = False
  • 1
  • 2
  • 3
  • 4

方法二(较麻烦,如果系统中无中文字体时使用)

(1)下载字体SimHei.ttf

在ubuntu系统,可能缺乏相应字体,需要自行下载

下载方式可以自行百度,或者在文末的网盘链接下载

(2)将字体上传到matplotlib的字体目录

使用下面的代码查看matplotlib的目录

import matplotlib
print(matplotlib.matplotlib_fname())
  • 1
  • 2

显示结果示例:

'/home/xiaobai/opt/anaconda3/lib/python3.6/site-packages/matplotlib/mpl-data/matplotlibrc'
  • 1

将下载的SimHei.ttf上传至上面代码输出目录的子目录fonts/ttf

示例目录

/home/xiaobai/opt/anaconda3/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/ttf
  • 1

注意,实际目录以代码运行结果为准

(3)清空matplotlib缓存

rm -rf  ~/.cache/matplotlib
  • 1

(4)设置刚才上传的中文字体

import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
  • 1
  • 2
  • 3
  • 4

2) 可视化

df = books.groupby('publish').count().sort('count', ascending=False).toPandas()
df.iloc[10::-1].set_index('publish').plot.barh()
  • 1
  • 2

在这里插入图片描述

7. 统计各出版社所出版书籍的平均评分

具体要求如下:

  • 只统计评论数在200以上的出版社
  • 按平均分从高到低排序
  • 可视化平均评分Top10

1)按要求统计平均分

  • DSL

    from pyspark.sql import functions as F
    #按出版社进行分组,并分别统计数量和评分的平均分
    pub_cnt_rate = books.groupby('publish').agg(F.count(F.col('id')).alias('count'), 
                                          F.mean(F.col('rate')).alias('avg_rate'))
    #筛选评论数大于200的数据,并按降序排列
    top_avg = pub_cnt_rate.filter(F.col('count')>200).sort('avg_rate', ascending = False)
    #显示数据
    top_avg.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    +------------------+-----+-----------------+
    |           publish|count|         avg_rate|
    +------------------+-----+-----------------+
    |            集英社|  465|9.001505358501147|
    |中国少年儿童出版社|  207|8.999033773578883|
    |            講談社|  426|8.939671380978794|
    |        东立出版社| 1223|8.926819284334597|
    |            小学館|  253|8.866007923608713|
    |        尖端出版社|  557| 8.78402155562834|
    |          台灣角川|  267|8.656554338190887|
    |    上海古籍出版社|  590|8.648813579042079|
    |          中华书局| 1278|8.647104871478252|
    |  世界图书出版公司|  269|8.635687769567213|
    |        接力出版社|  219| 8.63196347510978|
    |    人民邮电出版社|  599| 8.62036727465851|
    |  二十一世纪出版社|  323| 8.60743037539739|
    |          時報文化|  215|8.576279125657193|
    |中国建筑工业出版社|  209|8.540191401705217|
    |北京十月文艺出版社|  230|8.536086980156277|
    |    人民文学出版社| 1437|8.530897729498028|
    |    河北教育出版社|  385|8.528571470681722|
    |        商务印书馆|  917|8.522464596198196|
    |    机械工业出版社|  519|8.521194627059907|
    +------------------+-----+-----------------+
    only showing top 20 rows
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
  • SQL

    top_avg = spark.sql('''
    select * from (select publish, count(1) as count, avg(rate) as avg_rate 
    from books group by publish)
    where count > 200 order by avg_rate desc
    ''')
    top_avg.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

2) 可视化top10

import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

df = top_avg.toPandas()
df.iloc[10::-1, [0,2]].set_index('publish').plot.barh(legend=False,xlim = (8,10))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述

相关资源

链接:https://pan.baidu.com/s/15dm0Y-H1JQE0TcvWC4kL0w?pwd=dvzj 
提取码:dvzj 
  • 1
  • 2
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/193100
推荐阅读
相关标签
  

闽ICP备14008679号