Spark项目实践--基于 TMDB 数据集的电影数据分析

一、环境搭建

从假设裸机,环境搭建开始,具体环境搭建操作大体流程如下,具体详细流程点击查看另一篇博客:spark环境搭建
大体流程:
(1)安装Linux操作系统:比如可以安装Ubuntu 16.04
(2)安装Hadoop:需要在Linux系统上安装Hadoop
(3)安装Spark:需要在Linux系统上安装Spark
(4)最后为了方便编写代码,实现Linux与Windows下的pycharm对接。

本次实验环境:
pycharm2019专业版
Ubuntu16.04
pip3=10.0.1
pyspark3.0.2

二、数据预处理

环境搭建完成之后,开始做项目。
首先数据集介绍:
本次项目使用的数据集来自数据网站 Kaggle 的 tmdb-movie-metadata 电影数据集,该数据集包含大约 5000 部电影的相关数据。数据包含以下字段:
在这里插入图片描述
上图中可以看出数据中某些字段包含 json 数据,因此直接使用 DataFrame 进行读取会出现分割错误,所以如果要创建 DataFrame,需要先直接读取文件生成 RDD,再将 RDD 转为 DataFrame。过程中,还需要使用 python3 中的 csv 模块对数据进行解析和转换。

为了更方便的对 csv 文件转化的 RDD 进行处理,需要首先去除csv文件的标题行。完成后,将处理好的文件 tmdb_5000_movies.csv 存储到 HDFS 上方便进一步的处理,使用下面命令将文件上传至 HDFS:

hdfs dfs -put tmdb_5000_movies.csv

问题一
如果上传过程中遇到如下情况:hdfs: command not found
原因是没有在bin目录之下设置路径,解决:
1.sudo vi /etc/profile打开原文件
2.在文件最后新起一行添加路径export PATH=/usr/local/hadoop/bin:$PATH
其中这里的/usr/local/hadoop/bin是你的hdfs所在的目录,一定看清楚。
3.最后要使文件生效,这个一定不要忘了,不然文件也是白配置。命令:source /etc/profile

这时文件已经被上传至HDFS中

三、使用 Spark 将数据转为 DataFrame

打开Windows下的pycharm,连接到Linux,开始编程
因为读入的 csv 文件是结构化的数据,因此可以将数据创建为 DataFrame 方便进行分析。
上面也说过,为了创建DataFrame ,要将HDFS上的数据加载为RDD,由RDD转为DataFrame ,具体代码以及解析如下:

'''
csv --> HDFS--> RDD -->  DataFrame
1.创建 SparkSession 和 SparkContext 对象。
2.为 RDD 转为 DataFrame 制作表头 (schema)。schema 是一个 StructType 对象,
该对象使用一个 StructField 数组创建。
每一个 StructField 都代表结构化数据中的一个字段,构造 StructField 需要 3 个参数
1. 字段名称
2. 字段类型
3. 字段是否可以为空
'''
#这里运行之前的环境配置,有些不配置不会出错,不过由于不是直接在Linux里写的,而是对接的pycharm中,所以可能会出现环境错误,带上这几行代码以防万一
import os
os.environ["JAVA_HOME"] = "/usr/lib/jvm/jdk1.8.0_162"
os.environ["PYSPARK_PYTHON"] = "/usr/bin/python3.5"
#调用包
from pyspark import SparkContext
from pyspark.sql import SparkSession, Row
from pyspark.sql.types import StringType, StructField, StructType
import json # 用于后面的流程
import csv
import matplotlib.pyplot as plt

#创建两个对象
sc = SparkContext('local','spark_project')
sc.setLogLevel('WARN')
spark = SparkSession.builder.getOrCreate()

# 根据数据集表格制作表头
schemaString = "budget,genres,homepage,id," \
               "keywords,original_language," \
               "original_title,overview,popularity," \
               "production_companies,production_countries," \
               "release_date,revenue,runtime,spoken_languages," \
               "status,tagline,title,vote_average,vote_count"

fields = [StructField(field,StringType(),True)
          for field in schemaString.split(',')]

schema = StructType(fields)

# 3. 开始创建用于转为 DataFrame 的 RDD。这个过程首先sc.textFile读取 HDFS 上的数据文件,然后为了将 RDD 转为 DataFrame,还需要使用lambda函数将数据的每一行转为一个 Row 对象。
#lambda函数内部:对于每一行用逗号分隔的数据,(从里到外剖析)
# 1.csv.reader:使用 csv 模块进行解析并转为 Row 对象,得到可以转为 DataFrame 的 RDD
#2.使用 next 函数将迭代器中的数据读取到数组
#3.使用 * 将数组转为 Row 对象的构造函数参数,创建 Row 对象
moviesRdd = sc.textFile('tmdb_5000_movies.csv').map(lambda line: Row(*next(csv.reader([line]))))

#使用准备好的表头 (schema) 和 RDD 创建 DataFrame createDataFrame 创建 DataFrame
mdf = spark.createDataFrame(moviesRdd, schema)
#mdf.show() #至此完成 DataFrame 的创建,show查看最终内容
#print(mdf.collect())

以上数据预处理结束。最后可以打印出来查看数据结构,进行下面的数据分析。

四、使用 Spark 进行数据分析并可视化

接下来使用上述处理完成后得到的 DataFrame mdf 进行数据分析,首先对数据中的主要字段单独进行分析,然后再分析不同字段之间的关系。
为了方便使用matplotlib进行数据可视化,对于每个字段不同的分析,都将分析结果导出为json文件保存之后,对该文件进行数据可视化。
接下来的每个分析都需要进行保存,所以提前定义一个save函数,直接调用即可:

def save(path, data):
  with open(path, 'w') as f:
    f.write(data)

注意!!!下列代码中所有的save有关的函数如果被注释掉的请打开,否则存储不了的话,可视化分析是不可以的。

1.单独分析

(1)分析数据集中电影的体裁分布

  • 数据集中可以看出,电影的体裁字段是一个 json 格式的数据,所以,要统计不同体裁的电影的数量,首先需要解析这个字段的 json 数据,从中取出每个电影对应的体裁数组,然后使用词频统计的方法,根据相同key相加,统计不同体裁出现的频率,即可得到电影的体裁分布。
#选择体裁字段,filter筛选出数据中该字段为空的不要,使用map与lambda函数结合,
madff = mdf.select("genres").filter(mdf["genres"] != '').rdd.flatMap(
         lambda g: [(v, 1) for v in map(lambda x: x['name'], json.loads(g["genres"]))])\
         .repartition(1).reduceByKey(lambda x, y: x + y)
#print(mdf.collect()) #建议每打出一行代码就运行一下看看结果
res =madff.collect()
#print(list(map(lambda v: {"genre": v[0], "count": v[1]}, res)))
countByGenres=list(map(lambda v: {
   "genre": v[0], "count": v[1]}, res))
print(countByGenres)
#save('/home/hadoop/test/TMDB/genres.json', json.dumps(countByGenres))
#不可跨平台保存,注意路径,要是虚拟机的路径
#下面画图之前先读取保存的文件数据
with open('/home/hadoop/test/TMDB/genres.json', 'r') as f:
    data=json.load(f)
print(data)
#取出画图需要的x,y轴
x=list(map(lambda x:x['genre'],data)) #python自带的map与RDD中map区分开,python中map自动遍历值
y=list(map(lambda x:x['count'],data))
print(x)
print(y)
plt.bar(x,y,0.5)
plt.show()

(2) 前 100 个常见关键词

  • 该项分析电影关键词中出现频率最高的前一百个。字段也是 json 格式数据,因此也是进行频率统计,统计结果进行降序排序并取前 100 项。
#进行频率统计,同时对于统计结果进行降序排序并取前 100 项,套路如上,选择字段--筛选出无用值--词频统计
keyword = mdf.select("keywords").filter(mdf["keywords"] != '').rdd.flatMap(
         lambda g: [(v, 1) for v in map(lambda x: x['name'], json.loads(g["keywords"]))])\
         .repartition(
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值