Python案例实操3-电影数据分析
Python案例实操3-电影数据分析
- 一、读取数据
- 二、数据处理
- 1.索引重命名
- 2.合并数据集
- 3.选取子集
- 4.缺失值处理
- 5.数据格式转换
- 三、数据分析及可视化
- 1.电影类型随时间变化趋势图
- 2.统计电影分类情况
- 3.电影类型与利润的关系
- 4.Universal Pictures 和 Paramount Pictures 公司电影发行数据对比
- 5.改编电影和原创电影的对比情况
- 6.电影时长与电影票房及评分的关系
- 7.电影关键词分析
本案例数据来源于 kaggle 上的 Movie数据集,主要研究以下几个问题:
- 电影类型如何随着时间的推移发生变化的?
- 统计电影分类的情况?
- 电影类型与利润的关系?
- Universal 和 Paramount 两家影视公司的对比情况如何?
- 改编电影和原创电影的对比情况如何?
- 电影时长与电影票房及评分的关系?
- 分析电影关键字
实战开始:
一、读取数据
creditlist = pd.read_csv(r'E:\WorkSpaces\Python\data\tmdb\tmdb_5000_credits.csv')
movielist = pd.read_csv(r'E:\WorkSpaces\Python\data\tmdb\tmdb_5000_movies.csv')
二、数据处理
1.索引重命名
# 修改 creditlist中的列索引 字典格式{'old','new'},inplace=True表示在原数据上修改
creditlist.rename(columns={'movie_id': 'id', 'crew': 'directors', 'cast': 'actors'}, inplace=True)
# 修改 movielist中的列索引
movielist.rename(columns={'original_language': 'language','production_companies': 'companies', 'production_countries': 'countries'}, inplace=True)
2.合并数据集
合并数据集,注意列索引保持一致
# 数据合并 键指定 id 和 title
databoth = pd.merge(creditlist, movielist, on=['id', 'title'])
3.选取子集
选取子集,选择我们需要的列
# 筛选特征值(目标值)
# ['电影名称', '类型','语言', '导演','主演','首映日期','电影时长(分钟)','平均评分','评论次数','关键词','制作公司列表','制作国家列表','预算(美元)','收入(美元)','浏览次数']
datalist = pd.DataFrame(databoth,columns=['title', 'genres', 'language', 'directors', 'actors', 'release_date', 'runtime','vote_average', 'vote_count', 'keywords', 'companies','countries', 'budget', 'revenue', 'popularity'])
4.缺失值处理
少量缺失值可进行手动赋值处理,大量缺失值可使用dropna()删除或者fillna()替换
# 检测缺失值 isnull() + sum()
res_null = pd.isnull(datalist).sum()
print('缺失值检测结果:\n', res_null)
# 检测到release_date 有一条为空,runtime有两条为空
# 针对方式:手动填充,找出具体的电影名称,自己查找相关信息
# a、确定bool数组
mask = datalist.loc[:, 'release_date'].isnull()
mask2 = datalist.loc[:, 'runtime'].isnull()
# b、根据bool数组来获取缺失值位置的电影名称
movie_name = datalist.loc[mask, 'title']
movie_name2 = datalist.loc[mask2, 'title']
print('缺失上映日期的电影名称为:\n', movie_name)
# 4553 America Is Still the Place
# Name: title, dtype: object
print('缺失电影时长的电影名称为:\n', movie_name2)
# 2656 Chiamatemi Francesco - Il Papa della gente
# 4140 To Be Frank, Sinatra at 100
# Name: title, dtype: object
# c 、 填充
datalist.loc[mask, 'release_date'] = '2014-06-01'
datalist.iloc[2656, datalist.columns.get_indexer(['runtime'])] = 94
datalist.iloc[4140, datalist.columns.get_indexer(['runtime'])] = 81
5.数据格式转换
# 以类型为例 [{"id": 28, "name": "Action"}, {"id": 12, "name": "Adventure"}, {"id": 14, "name": "Fantasy"}, {"id": 878, "name": "Science Fiction"}]
# 转换成 Action,Adventure,Fantasy,Science Fiction 格式def data_format(datas):"""数据格式转换:param datas: 数据:return: 转换之后的数据"""name_list = []# 遍历 列表for item in datas:# 如果item存在if item:movie_type = item['name']name_list.append(movie_type)return ','.join(name_list)# --电影类型 格式转换--
print('电影类型:\n', datalist.loc[:, 'genres']) # json数据类型
# json.loads # 可以将json转化为python类型
# 将 datalist.loc[:, 'genres'] 由 json类型转化为 python类型
datalist.loc[:, 'genres'] = datalist.loc[:, 'genres'].transform(json.loads)
# 调用方法 疑问?这里是怎么调用方法的,参数怎么传的
datalist.loc[:, 'genres'] = datalist.loc[:, 'genres'].transform(data_format)
print('电影类型 转换之后的结果:\n', datalist.loc[:, 'genres'])# 其他字段转换类似,此处不再重复展示...
三、数据分析及可视化
1.电影类型随时间变化趋势图
思路:
- 在每行数据后追加所有电影类型列,初始值为0
- 遍历每一部电影的’genres’列,把分类包含在该列中的值置为1
- 分组并按照类型求和
# 将 release_date 转化为 pandas支持的时间序列
datalist.loc[:, 'release_date'] = pd.to_datetime(datalist.loc[:, 'release_date'])
# 获取 发行年份
datalist.loc[:, 'release_year'] = datalist.loc[:, 'release_date'].dt.year# 进行字符串分割
temp_list = [i.split(",") for i in datalist["genres"]]
# 获取电影的分类,并去重
typelist = np.unique([i for j in temp_list for i in j])
# 发现typelist中有空值,删除空元素''
typelist = np.delete(typelist, typelist == '')
for column in typelist:# 先增加所有电影类型列,初始值为0datalist.loc[:, column] = 0# 构建bool数组mask = datalist.loc[:, 'genres'].str.contains(column)# 修改datalist.loc[mask, column] = 1# 按照发行年份进行分组,统计各个电影各个年份的数量
res = datalist.groupby('release_year')[typelist].sum()
print(res)# 绘图
# 创建画布
plt.figure()
# 默认不支持中文 ---修改RC参数
plt.rcParams['font.sans-serif'] = 'SimHei'
# 增加字体之后变得不支持负号,需要修改RC参数让其继续支持负号
plt.rcParams['axes.unicode_minus'] = False
# 构建横轴数据
x = res.index
for movie_type in res.columns:# 构建纵轴数据y = res[movie_type]# 绘制折线图plt.plot(x, y)
# 增加标题
plt.title('电影类型随时间变化趋势图')
# 设置图例
plt.legend(res.columns, fontsize='x-small')
# 设置纵轴名称
plt.ylabel('数量')
# 设置横轴名称
plt.xlabel('年份')
# 增加网络曲线
plt.grid(True, alpha=0.2)
# 保存图片
plt.savefig('./电影类型随时间变化趋势图.jpg')
# 展示
plt.show()
2.统计电影分类情况
思路
1、创建一个全为0的dataframe,列索引置为电影的分类,temp_df
2、遍历每一部电影,temp_df中把分类出现的列的值置为1
3、求和
# 创建一个全为0的dataframe, 行大小为电影数据列表的行数,列大小为全部电影类型的数量(去重后),用于统计每种类型的电影数量
temp_df = pd.DataFrame(np.zeros([datalist.shape[0], typelist.shape[0]], dtype=int), columns=typelist)
# 遍历每一部电影,temp_df中把分类出现的列的值置为1
for i in range(datalist.shape[0]):# temp_list[i] ['Action','Adventure','Animation']# 通过行列索引值进行赋值temp_df.iloc[i, temp_df.columns.get_indexer(temp_list[i])] = 1# 求和、绘图
temp_df.sum().sort_values().plot(kind="pie", figsize=(20, 8), fontsize=10, autopct="%.2f", title='电影分类情况统计')
# 默认不支持中文 ---修改RC参数
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.savefig('电影分类情况统计.jpg')
3.电影类型与利润的关系
对比 各种电影类型 的 平均利润 —柱状图
Music —> profit — sum / music 电影的数量 count ===>平均每一个music电影的利润
# 计算 利润
datalist.loc[:, 'profit'] = datalist.loc[:, 'revenue'] - datalist.loc[:, 'budget']
print('利润:\n', datalist.loc[:, 'profit'])# 构建一个list来存储各种类型电影的平均利润
movie_type_profit = []
# 遍历 所有的 电影类型
for column in typelist:# column : 各种电影类型# 确定bool数组 ---为True的电影,属于mtype类型mask = datalist.loc[:, column] == 1# 筛选 column 类型电影 --该类型电影利润的平均值mean_profit = datalist.loc[mask, 'profit'].mean()# 加入到 movie_type_profitmovie_type_profit.append(mean_profit)print(typelist)
print(movie_type_profit)
# 创建series
res_series = pd.Series(data=movie_type_profit, index=typelist).sort_values()
# 绘图
res_series.plot(kind="barh", figsize=(20, 8), fontsize=10, title='电影类型和利润关系图', ylabel='电影分类')
# 默认不支持中文 ---修改RC参数
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.savefig('电影类型和利润关系图.jpg')
4.Universal Pictures 和 Paramount Pictures 公司电影发行数据对比
1)Universal Pictures 和 Paramount Pictures 公司电影发行量对比
对’companies’列数据进行处理,判断是否包含Universal Pictures 或 Paramount Pictures公司
# 先增加两列数据 两家公司发行的电影数量
datalist.loc[:, 'Universal Pictures'] = 0
datalist.loc[:, 'Paramount Pictures'] = 0
# 判断 ---bool数组,包含Universal Pictures公司
mask1 = datalist.loc[:, 'companies'].str.contains('Universal Pictures')
# 修改
datalist.loc[mask1, 'Universal Pictures'] = 1# 判断 --bool数组,包含Paramount Pictures公司
mask2 = datalist.loc[:, 'companies'].str.contains('Paramount Pictures')
# 修改
datalist.loc[mask2, 'Paramount Pictures'] = 1# 发行量计算
res_pie = datalist.loc[:, ['Universal Pictures', 'Paramount Pictures']].sum()# 绘图
res_pie.plot(kind="pie", figsize=(20, 8), fontsize=10, autopct="%d", title='电影发行量对比图')
# 默认不支持中文 ---修改RC参数
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.savefig('电影发行量对比图.jpg')
2)分析 Universal Pictures 和 Paramount Pictures 两家影视公司电影发行量随时间变化的趋势
按照 release_year分组,对发行数量求和
# 查看两家公司发行量随时间变化趋势
# 按照 release_year分组,统计两家公司每年的发行数量
res_line = datalist.groupby(by='release_year')[['Universal Pictures', 'Paramount Pictures']].sum()
res_line.plot(figsize=(20, 8), fontsize=20, title='发行量随时间变化趋势')
plt.ylabel('发行量')
plt.xlabel('时间')
plt.savefig('发行量随时间变化趋势.jpg')
5.改编电影和原创电影的对比情况
如何确定电影是改编的?还是原创的呢?
与电影相关的关键字 keywords
如果在这里是根据小说改编的 base on novel/fairy tale/…
只要出现 base on 这个字眼 就说明 是改编的
# 先增加一列
datalist.loc[:, 'not_original'] = '原创'
# 确定bool数组,如果是改编的,那就将 not_original 修改为'not_original'
mask = datalist.loc[:, 'keywords'].str.contains('based on')
# 修改
datalist.loc[mask, 'not_original'] = '改编'# 按照是否原创进行分组,统计原创电影的平均预算、收入、利润
# 计算 利润
datalist.loc[:, 'profit'] = datalist.loc[:, 'revenue'] - datalist.loc[:, 'budget']
res_not_original = datalist.groupby('not_original')[['budget', 'revenue', 'profit']].mean()
print('res_not_original\n', res_not_original)# 绘图
res_not_original.plot(kind="bar", figsize=(20, 8), fontsize=20, title='原创与改编电影预算、收入、利润对比柱状图')
# 默认不支持中文 ---修改RC参数
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.ylabel('美元')
plt.xlabel('原创或改编')
plt.savefig('原创与改编电影预算、收入、利润对比柱状图.jpg')
6.电影时长与电影票房及评分的关系
按照 电影时长 分组,查看不同电影时长的平均票房、平均评分
1、自定义时长分组
2、进行离散化
3、分组聚合,对票房和评分进行求均值
print('查看电影时长、票房、评分:\n', datalist.loc[:, ['runtime', 'revenue', 'vote_average']].head())
# 1、自定义时长分组
bins = [0, 60, 90, 120, 150, 180, 210, 240]
# 2、数据离散化
datalist.loc[:, 'runtime'] = pd.cut(x=datalist.loc[:, 'runtime'],bins=bins,include_lowest=True)
# 3、分组聚合,对票房和评分进行求均值
res_runtime = datalist.groupby('runtime')[['revenue', 'vote_average']].mean().sort_values(by=['revenue', 'vote_average'])
print('res_runtime:\n', res_runtime)# 绘图 指定评分列vote_average使用右y轴(子图)
ax = res_runtime.plot(secondary_y=['vote_average'], figsize=(10, 5), title='不同时长的电影票房、评分的对比柱状图')
ax.set_xlabel('时长(分钟)')
ax.set_ylabel('票房(美元)')
ax.right_ax.set_ylabel('评分') # 右y轴的标签
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.savefig('不同时长的电影票房、评分的对比柱状图.jpg')
7.电影关键词分析
生成电影关键词词云
from wordcloud import WordCloud, STOPWORDSkeywords_list = []for x in datalist['keywords']:keywords_list.append(x)str_key = ''.join(keywords_list)str_key.replace('\'s', '')# 设置停用词stopwords = STOPWORDSstopwords.update(['based', 'film'])# 封装词云wc = WordCloud(background_color="white",font_path="simkai.ttf", # 字体 C:\Windows\Fontsstopwords=stopwords)wc.generate_from_text(str_key)# 绘制图片plt.figure(figsize=(10, 5))plt.imshow(wc)plt.axis("off") # 不显示坐标轴plt.savefig(r'电影关键词.jpg')
参考文章:https://blog.csdn.net/markshui/article/details/108214328
Python案例实操3-电影数据分析相关推荐
- python案例实操_用案例实操学习Python ,培养编程逻辑思维
案例一: A.B.C.D.E 五人在某天夜里合伙去捕鱼,到第二天凌晨时都疲惫不堪,于是各自找地方睡觉. 日上三杆 A 第一个醒来,他将鱼分为五份,把多余的一条鱼扔掉,拿走自己的一份. B 第二个醒来, ...
- 数据模型同学看过来|代码案例实操来袭
去年年底,央行开出反洗钱罚单,多家银行合计被罚1040万元. 当时,中国人民银行石家庄中心支行披露的反洗钱行政处罚信息公示表显示,因涉及未按照规定履行客户身份识别义务等,中行.邮储.浦发三家银行以及阳 ...
- MapReduce入门(一)—— MapReduce概述 + WordCount案例实操
MapReduce入门(一)-- MapReduce概述 文章目录 MapReduce入门(一)-- MapReduce概述 1.1 MapReduce 定义 1.2 MapReduce 优缺点 1. ...
- 【李刚-21天通关Python-27】之 案例实操:函数装饰器应用
[李刚-21天通关Python-27]之 案例实操:函数装饰器应用 一.函数装饰器的广泛应用 @staticmethod 和 @classmethod 的本质就是函数装饰器 staticmethod ...
- 大数据之Spark案例实操完整使用(第六章)
大数据之Spark案例实操完整使用 一.案例一 1.准备数据 2.需求 1:Top10 热门品类 3.需求说明 方案一. 实现方案二 实现方案三 二 .需求实现 1.需求 2:Top10 热门品类中每 ...
- 新硬盘挂载-fdisk+mount案例实操
新硬盘挂载-fdisk+mount案例实操 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 现在很多服务器都支持热插拔了,当有新的硬盘插入到服务器上我们需要将其分区,格式化,然后挂载 ...
- 【报告分享】见实私域流量白皮书:私域流量案例实操手册.pdf
大家好,我是文文(微信:sscbg2020),今天给大家分享见实科技于2020年10月份发布的报告<见实私域流量白皮书:私域流量案例实操手册.pdf>. 本报告共73页,包含如下鞋服.餐饮 ...
- 自定义OutputFormat案例实操
自定义OutputFormat案例实操 文章目录 1)需求 2)需求分析 3)编程实现 1.创建Mapper类 2.创建Reducer类 3.创建OutputFormat类 4.创建RecordWri ...
- Azkaban配置Work Flow案例实操
Work Flow案例实操 目录 Work Flow案例实操 1. Yarm语法简介 2. HelloWorld案例 3. JavaProcess案例 4. 作业依赖案例 5. 自动失败重试案例 6. ...
- 航空专场 | 无人机设计仿真流程讲解与案例实操
一.CFD在无人机上的应用 1.静.动气动系数计算以上介绍的无人机的流动状态一般为中低雷诺数,不可压缩流动.这些计算一般用S-A模型或者KW-SST模型进行计算,能够获得不错的工程精度.静.动气动力系 ...
最新文章
- Redis 读写分离技术架构解析
- BZOJ1061 [NOI2008]志愿者招募
- 黑马程序员java笔记之二-----多线程
- deepin linux下python安装mysqldb
- Kafka 教程(二) 集群搭建和容错性测试
- Linux kernel 3.10内核源码分析--进程上下文切换
- 《超越需求:敏捷思维模式下的分析》—第1章 1.1节简介
- pytorch实现LeNet5
- linux网络编程之socket:使用fork并发处理多个client的请求
- Android开发笔记(一百七十九)避免方法数过多的问题
- 联想高校AI精英挑战赛再下一城,10项目逐鹿华中科大,智能大数据平台夺冠
- 打造机器人:为遥控小车加一个树莓派
- 2018 考研 408 经验贴——总结篇
- SRGAN——使用与超分辨率重建的GAN
- 区块链简介与PMD投资方式
- 沪深300期权可以程序化交易吗?
- Spring boot 2 雷神
- 手把带你学会红外避障循迹模块
- ATM(异步传输模式)是什么?
- 自定义View之指南针(反编译别人的代码实现)