电影数据分析系统 | Spark Hadoop Python Django 机器学习驱动票房预测与推荐 大数据 人工智能 毕业设计源码(建议收藏)✅
博主介绍:✌全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久,选择我们就是选择放心、选择安心毕业✌
> 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与我联系了。🍅🍅感兴趣的可以先收藏起来,点赞、关注不迷路,大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助同学们顺利毕业 。🍅
1、毕业设计:2026年计算机专业毕业设计选题汇总(建议收藏)✅
2、大数据毕业设计:2026年选题大全 深度学习 python语言 JAVA语言 hadoop和spark(建议收藏)✅
1、项目介绍
技术栈
融合大数据技术(Hadoop、Spark、Hive)与虚拟机环境,以Python为核心开发语言,基于Django框架搭建架构,搭配MySQL数据库存储数据,运用协同过滤推荐算法、随机森林回归模型等机器学习技术,结合猫眼电影数据实现票房预测与电影推荐。
功能模块
- 电影数据大屏
- 电影类型分析
- 电影评分分析
- 电影时间分析
- 票房分析
- 数据中心
- 电影推荐
- 词云图分析
- 票房预测
- 我的收藏
- 后台管理
- spark数据分析
- 数据采集
项目介绍
本项目围绕电影数据分析系统的开发与实现展开,依托Spark等大数据技术处理海量电影数据,结合Python、Django搭建Web架构,MySQL存储结构化数据。系统集成数据采集、多维度可视化分析、基于随机森林的票房预测、协同过滤算法的电影推荐等功能,通过Echarts将分析结果可视化呈现。系统可高效处理电影数据,输出精准的票房预测与个性化推荐结果,为电影行业提供数据支撑与决策依据,具备功能完整、运行稳定的特点。
2、项目界面
电影数据大屏
集成了多类数据展示功能:通过饼图呈现类型占比,列表展示影片信息,柱状图统计票房评分,折线图分析类型票房趋势,还有国家发行、电影票房占比等图表,可直观查看电影多维度数据的统计、分布与趋势,实现电影数据的综合可视化分析。
电影类型分析
左侧设含多种分析功能的导航栏,页面主体通过折线图展示指定类型电影的票房 TOP10 数据,搭配柱状图呈现该类型评分分布,同时以饼图展示各类型电影平均时长,支持查看特定类型电影的多维度数据统计与分布情况,实现分类型电影数据的可视化分析。
电影评分分析
左侧设含多种数据功能的导航栏,页面主体通过柱状图展示年度评分值分布,以折线图呈现地区评分值变化,还包含类型评分值分析板块,可查看电影在年度、地区、类型维度的评分数据情况,实现多维度电影评分的可视化统计与分析。
电影时间分析
左侧设含各类数据功能的导航栏,页面主体通过柱状图展示电影年度、月度的产量分布,搭配饼图呈现电影时长的分类占比,可查看电影在产量时间维度及时长分类维度的数据情况,实现电影产量与时长的多维度可视化统计与分析。

票房分析
左侧设含各类数据功能的导航栏,页面主体通过折线图展示各类型电影票房走势,用柱状图呈现年度票房值分布,还包含各地区票房分析板块,可查看电影在类型、年度、地区维度的票房数据情况,实现多维度电影票房的可视化统计与分析。
数据中心
左侧设含各类数据功能的导航栏,页面主体以列表形式展示电影的名称、类型、时长、评分等详细信息,配备搜索框可检索内容,同时支持勾选操作,实现电影数据的集中展示、查阅与检索管理。
电影推荐
左侧设含各类数据功能的导航栏,页面主体以卡片形式展示推荐电影的海报、名称、简介、时长等信息,配备 “收藏” 按钮支持用户收藏影片,实现电影推荐内容的展示与收藏操作管理。
词云图分析
左侧设含各类数据功能的导航栏,页面主体展示电影相关关键词组成的词云图,通过文字大小差异体现关键词的热度分布,实现电影相关元素的可视化统计与直观呈现,帮助用户快速了解电影领域的高频内容。
票房预测
左侧设含各类数据功能的导航栏,页面主体提供类型、地区、首周票房的条件选择栏与查询按钮,提交后展示对应条件下的票房预测结果,实现根据指定条件进行电影票房的预测计算与结果展示。

我的收藏
左侧设含各类数据功能的导航栏,页面主体以卡片形式展示电影海报、名称、类型、地区、时长等信息,配备 “获取数据” 按钮,实现电影相关数据的集中展示与数据获取操作,便于后续分析或预测使用。

后台管理
左侧设包含历史表、用户表等功能的导航栏,页面主体展示快速操作区域(含登录、用户表等功能入口)与最近动作板块,实现后台管理功能的快速访问与操作记录查看,辅助管理员高效管理系统数据与权限。
spark数据分析
左侧展示项目文件结构,中间编辑区包含 Spark 会话初始化、数据读取、字段拆分与分组统计的代码,底部显示数据结果,实现通过 Spark 完成数据读取、处理及统计分析的功能,支持代码编写与数据分析结果查看。
数据采集
左侧展示项目文件结构,中间编辑区是数据读取、字段处理的代码,右侧显示电影详情页面,底部呈现采集的电影数据信息,实现从网页采集电影数据、通过代码处理数据的功能,支持数据采集、代码编写与数据信息查看。
3、项目说明
一、技术栈简要说明
本项目融合大数据技术(Hadoop、Spark、Hive)与虚拟机环境,以Python为核心开发语言,基于Django框架搭建Web架构,搭配MySQL数据库存储结构化数据;运用协同过滤推荐算法、随机森林回归模型等机器学习技术,结合猫眼电影数据,实现电影数据的采集、分析、预测与推荐全流程。
二、功能模块详细介绍
- 电影数据大屏:集成多类数据展示功能,通过饼图呈现电影类型占比,列表展示影片基础信息,柱状图统计票房与评分关联数据,折线图分析不同类型电影的票房趋势,同时包含国家发行分布、电影票房占比等图表,可直观呈现电影多维度数据的统计、分布与趋势,实现电影数据的综合可视化分析。
- 电影类型分析:左侧设多分析功能导航栏,页面主体以折线图展示指定类型电影的票房TOP10数据,搭配柱状图呈现该类型电影的评分分布情况,同时用饼图展示各类型电影的平均时长占比,支持查看特定类型电影的多维度数据统计与分布,实现分类型电影数据的精细化可视化分析。
- 电影评分分析:左侧设多数据功能导航栏,页面主体通过柱状图展示不同年度电影的评分值分布,以折线图呈现各地区电影的评分值变化趋势,还包含类型维度的评分分析板块,可查看电影在年度、地区、类型维度的评分数据,实现多维度电影评分的可视化统计与分析。
- 电影时间分析:左侧设各类数据功能导航栏,页面主体用柱状图展示电影年度、月度的产量分布情况,搭配饼图呈现电影时长的分类占比,可查看电影在产量时间维度及时长分类维度的数据,实现电影产量与时长的多维度可视化统计与分析。
- 票房分析:左侧设各类数据功能导航栏,页面主体通过折线图展示各类型电影的票房走势,用柱状图呈现不同年度的票房值分布,同时包含各地区票房分析板块,可查看电影在类型、年度、地区维度的票房数据,实现多维度电影票房的可视化统计与分析。
- 数据中心:左侧设各类数据功能导航栏,页面主体以列表形式展示电影的名称、类型、时长、评分等详细信息,配备搜索框支持内容检索,同时提供勾选操作功能,实现电影数据的集中展示、查阅与检索管理。
- 电影推荐:左侧设各类数据功能导航栏,页面主体以卡片形式展示推荐电影的海报、名称、简介、时长等信息,配备“收藏”按钮支持用户收藏影片,实现电影推荐内容的展示与收藏操作管理。
- 词云图分析:左侧设各类数据功能导航栏,页面主体展示由电影相关关键词组成的词云图,通过文字大小差异体现关键词的热度分布,实现电影相关元素的可视化统计与直观呈现,帮助用户快速了解电影领域的高频内容。
- 票房预测:左侧设各类数据功能导航栏,页面主体提供电影类型、发行地区、首周票房的条件选择栏与查询按钮,提交条件后展示对应场景下的票房预测结果,实现根据指定条件进行电影票房的预测计算与结果展示。
- 我的收藏:左侧设各类数据功能导航栏,页面主体以卡片形式展示电影海报、名称、类型、地区、时长等信息,配备“获取数据”按钮,实现电影相关数据的集中展示与数据获取操作,便于后续分析或预测使用。
- 后台管理:左侧设包含历史表、用户表等功能的导航栏,页面主体展示快速操作区域(含登录、用户表等功能入口)与最近动作板块,实现后台管理功能的快速访问与操作记录查看,辅助管理员高效管理系统数据与权限。
- spark数据分析:左侧展示项目文件结构,中间编辑区包含Spark会话初始化、数据读取、字段拆分与分组统计的代码,底部显示数据处理结果,实现通过Spark完成电影数据的读取、处理及统计分析,支持代码编写与数据分析结果查看。
- 数据采集:左侧展示项目文件结构,中间编辑区是数据读取、字段处理的代码,右侧显示电影详情页面,底部呈现采集的电影数据信息,实现从网页采集电影数据、通过代码处理数据的功能,支持数据采集、代码编写与数据信息查看。
三、项目总结
本电影数据分析系统依托大数据技术与机器学习算法,实现了电影数据从采集、处理、分析到预测、推荐的全流程覆盖。系统以Python、Django为基础搭建稳定的Web架构,结合Spark等大数据工具高效处理海量数据,通过Echarts完成可视化呈现,同时借助随机森林、协同过滤算法输出精准的票房预测与个性化推荐结果。系统功能完整、运行稳定,可高效为电影行业提供数据支撑与决策依据,后续可进一步优化算法模型、拓展数据源,提升智能化水平。

4、核心代码
#导包
from pyspark.sql import SparkSession
from pyspark.sql.functions import monotonically_increasing_id
from pyspark.sql.types import StructType,StructField,IntegerType,StringType,FloatType
from pyspark.sql.functions import count,mean,col,sum,when,max,min,avg,explode,split,row_number,year,month
from pyspark.sql.window import Window
if __name__ == '__main__':
#构建
spark = SparkSession.builder.appName("sparkSQL").master("local[*]"). \
config("spark.sql.shuffle.partitions", 2). \
config("spark.sql.warehouse.dir", "hdfs://node1:8020/user/hive/warehouse"). \
config("hive.metastore.uris", "thrift://node1:9083"). \
enableHiveSupport(). \
getOrCreate()
#读取
catMovieData = spark.read.table("catMovieData")
#需求一 类型分析 统计
explode_df = catMovieData.withColumn("type",explode(split(col("type"),"-")))
result1 = explode_df.groupBy("type").agg(count("type").alias("type_count"))
# sql
result1.write.mode("overwrite"). \
format("jdbc"). \
option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
option("dbtable", "movieTypeCount"). \
option("user", "root"). \
option("password", "root"). \
option("encoding", "utf-8"). \
save()
result1.write.mode("overwrite").saveAsTable("movieTypeCount", "parquet")
spark.sql("select * from movieTypeCount").show()
#需求二 票房TOP10
sorted_df =catMovieData.orderBy(col("allBoxOffice").desc())
result2 = sorted_df.limit(10)
# sql
result2.write.mode("overwrite"). \
format("jdbc"). \
option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
option("dbtable", "boxTopMovie"). \
option("user", "root"). \
option("password", "root"). \
option("encoding", "utf-8"). \
save()
result2.write.mode("overwrite").saveAsTable("boxTopMovie", "parquet")
spark.sql("select * from boxTopMovie").show()
#需求三 类型最大票房
result3 = explode_df.groupBy("type").agg(
max("firstBoxOffice").alias("max_firstBoxOffice"),
max("allBoxOffice").alias("max_allBoxOffice")
)
# sql
result3.write.mode("overwrite"). \
format("jdbc"). \
option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
option("dbtable", "typeMaxBox"). \
option("user", "root"). \
option("password", "root"). \
option("encoding", "utf-8"). \
save()
result3.write.mode("overwrite").saveAsTable("typeMaxBox", "parquet")
spark.sql("select * from typeMaxBox").show()
#需求四 国家统计
explode_df2 = catMovieData.withColumn("country",explode(split(col("country"),",")))
result4 = explode_df2.groupBy("country").agg(count("country").alias("country_count"))
# sql
result4.write.mode("overwrite"). \
format("jdbc"). \
option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
option("dbtable", "mcountryCount"). \
option("user", "root"). \
option("password", "root"). \
option("encoding", "utf-8"). \
save()
result4.write.mode("overwrite").saveAsTable("mcountryCount", "parquet")
spark.sql("select * from mcountryCount").show()
#需求五 评分分类
catMovieData = catMovieData.withColumn(
"rateCategory",
when(col("rate") == 0, None).otherwise(
when((col("rate") >= 10) & (col("rate") < 20), "半星").
when((col("rate") >= 20) & (col("rate") < 30), "1星").
when((col("rate") >= 30) & (col("rate") < 40), "1.5星").
when((col("rate") >= 40) & (col("rate") < 50), "2星").
when((col("rate") >= 50) & (col("rate") < 60), "2.5星").
when((col("rate") >= 60) & (col("rate") < 70), "3星").
when((col("rate") >= 70) & (col("rate") < 80), "3.5星").
when((col("rate") >= 80) & (col("rate") < 90), "4星").
when((col("rate") >= 90) & (col("rate") < 100), "4.5星")
)
)
filter_df = catMovieData.filter(col("rate") != 0)
result5 = filter_df.groupBy("rateCategory").count()
# sql
result5.write.mode("overwrite"). \
format("jdbc"). \
option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
option("dbtable", "starCategory"). \
option("user", "root"). \
option("password", "root"). \
option("encoding", "utf-8"). \
save()
result5.write.mode("overwrite").saveAsTable("starCategory", "parquet")
spark.sql("select * from starCategory").show()
#需求6 按类型票房分析
grouped_df = explode_df.groupBy("type","title").agg({"allBoxOffice":"sum"})
grouped_df = grouped_df.withColumnRenamed("sum(allBoxOffice)","allBoxOffice")
window = Window.partitionBy("type").orderBy(col("allBoxOffice").desc())
ranked_df = grouped_df.withColumn("row_num",row_number().over(window))
#过滤出每组的前十
result6 = ranked_df.filter(col("row_num") <= 10).drop("row_num")
# sql
result6.write.mode("overwrite"). \
format("jdbc"). \
option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
option("dbtable", "perTypeBox"). \
option("user", "root"). \
option("password", "root"). \
option("encoding", "utf-8"). \
save()
result6.write.mode("overwrite").saveAsTable("perTypeBox", "parquet")
spark.sql("select * from perTypeBox").show()
#需求7 按类型评分
filter_df2 = explode_df.filter(col("rate") != 0)
result7 = filter_df2.groupBy("type","rate").agg(count("rate").alias("rate_count"))
# sql
result7.write.mode("overwrite"). \
format("jdbc"). \
option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
option("dbtable", "perTypeRate"). \
option("user", "root"). \
option("password", "root"). \
option("encoding", "utf-8"). \
save()
result7.write.mode("overwrite").saveAsTable("perTypeRate", "parquet")
spark.sql("select * from perTypeRate").show()
#需求8类型平均时长
result8 = explode_df.groupBy("type").agg(avg("duration").alias("avg_duration"))
# sql
result8.write.mode("overwrite"). \
format("jdbc"). \
option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
option("dbtable", "typeAvgTime"). \
option("user", "root"). \
option("password", "root"). \
option("encoding", "utf-8"). \
save()
result8.write.mode("overwrite").saveAsTable("typeAvgTime", "parquet")
spark.sql("select * from typeAvgTime").show()
#需求9 年度平均评分分析
time_df1 = catMovieData.withColumn("releaseTime",col("releaseTime").cast("date"))
time_df2 = catMovieData.withColumn("year",year(col("releaseTime")))
result9 = time_df2.groupBy("year").agg(avg("rate").alias("year_rate"))
# sql
result9.write.mode("overwrite"). \
format("jdbc"). \
option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
option("dbtable", "mYearRate"). \
option("user", "root"). \
option("password", "root"). \
option("encoding", "utf-8"). \
save()
result9.write.mode("overwrite").saveAsTable("mYearRate", "parquet")
spark.sql("select * from mYearRate").show()
#需求十 国家平均
result10 = explode_df2.groupBy("country").agg(avg("rate").alias("avg_rate"))
# sql
result10.write.mode("overwrite"). \
format("jdbc"). \
option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
option("dbtable", "mCountryRate"). \
option("user", "root"). \
option("password", "root"). \
option("encoding", "utf-8"). \
save()
result10.write.mode("overwrite").saveAsTable("mCountryRate", "parquet")
spark.sql("select * from mCountryRate").show()
#需求十一 类型
result11 = explode_df.groupBy("type").agg(avg("rate").alias("avg_rate"))
# sql
result11.write.mode("overwrite"). \
format("jdbc"). \
option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
option("dbtable", "mTypeRate"). \
option("user", "root"). \
option("password", "root"). \
option("encoding", "utf-8"). \
save()
result11.write.mode("overwrite").saveAsTable("mTypeRate", "parquet")
spark.sql("select * from mTypeRate").show()
#需求十二 时间分析
result12 = time_df2.groupBy("year").agg(count("year").alias("year_count"))
# sql
result12.write.mode("overwrite"). \
format("jdbc"). \
option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
option("dbtable", "mYearCount"). \
option("user", "root"). \
option("password", "root"). \
option("encoding", "utf-8"). \
save()
result12.write.mode("overwrite").saveAsTable("mYearCount", "parquet")
spark.sql("select * from mYearCount").show()
#月度
time_df3 = time_df1.withColumn("month",month(col("releaseTime")))
result13 = time_df3.groupBy("month").agg(count("month").alias("year_count"))
# sql
result13.write.mode("overwrite"). \
format("jdbc"). \
option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
option("dbtable", "mMonthCount"). \
option("user", "root"). \
option("password", "root"). \
option("encoding", "utf-8"). \
save()
result13.write.mode("overwrite").saveAsTable("mMonthCount", "parquet")
spark.sql("select * from mMonthCount").show()
#时长分析
catMovieData = catMovieData.withColumn(
"durationCategory",
when(col("duration") == 0, None).otherwise(
when((col("duration") >= 0) & (col("rate") < 50), "很短").
when((col("duration") >= 50) & (col("rate") < 80), "较短").
when((col("duration") >= 80) & (col("rate") < 120), "中").
when((col("duration") >= 120) & (col("rate") < 150), "较长").
otherwise('很长')
)
)
filter_df4 = catMovieData.filter(col("duration") != 0)
result14 = filter_df4.groupBy("durationCategory").count()
# sql
result14.write.mode("overwrite"). \
format("jdbc"). \
option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
option("dbtable", "mTimeCategory"). \
option("user", "root"). \
option("password", "root"). \
option("encoding", "utf-8"). \
save()
result14.write.mode("overwrite").saveAsTable("mTimeCategory", "parquet")
spark.sql("select * from mTimeCategory").show()
#需求15 各类型平均票房
result15 = explode_df.groupBy("type").agg(
avg("allBoxOffice").alias("avg_allBoxOffice")
)
# sql
result15.write.mode("overwrite"). \
format("jdbc"). \
option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
option("dbtable", "mTypeAvgBox"). \
option("user", "root"). \
option("password", "root"). \
option("encoding", "utf-8"). \
save()
result15.write.mode("overwrite").saveAsTable("mTypeAvgBox", "parquet")
spark.sql("select * from mTypeAvgBox").show()
#各国家票房
result16 = explode_df2.groupBy("country").agg(
avg("allBoxOffice").alias("avg_allBoxOffice")
)
# sql
result16.write.mode("overwrite"). \
format("jdbc"). \
option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
option("dbtable", "mCountryAvgBox"). \
option("user", "root"). \
option("password", "root"). \
option("encoding", "utf-8"). \
save()
result16.write.mode("overwrite").saveAsTable("mCountryAvgBox", "parquet")
spark.sql("select * from mCountryAvgBox").show()
#年度平均票房
result17 = time_df2.groupBy("year").agg(
avg("allBoxOffice").alias("avg_allBoxOffice")
)
# sql
result17.write.mode("overwrite"). \
format("jdbc"). \
option("url", "jdbc:mysql://node1:3306/bigdata?useSSL=false&useUnicode=true&charset=utf8"). \
option("dbtable", "mYearAvgBox"). \
option("user", "root"). \
option("password", "root"). \
option("encoding", "utf-8"). \
save()
result17.write.mode("overwrite").saveAsTable("mYearAvgBox", "parquet")
spark.sql("select * from mYearAvgBox").show()
5、源码获取方式
🍅由于篇幅限制,获取完整文章或源码、代做项目的,查看我的【用户名】、【专栏名称】、【顶部选题链接】就可以找到我啦🍅
感兴趣的可以先收藏起来,点赞、关注不迷路,下方查看👇🏻获取联系方式👇🏻
更多推荐




所有评论(0)