import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)
# 加载数据
def load_data():
# 加载电影票房
open_filepath = 'D:\pythondata\\3、猫眼电影\\box_result.csv'
movie_box = pd.read_csv(open_filepath)
movie_box = movie_box[['电影id', '电影名称','首映日期','总票房']].drop_duplicates()
# 加载电影信息
open_filepath = 'D:\pythondata\\3、猫眼电影\\maoyan_movie.xlsx'
movie_message = pd.read_excel(open_filepath,sheet_name='maoyan_movie')
movie_message.columns = ['电影url','电影名称','电影题材','国家','上映时间','用户评分','电影简介','导演/演员/编剧']
movie_message = movie_message[['电影url','电影题材','国家','用户评分','导演/演员/编剧']].copy()
movie_message.drop_duplicates(inplace=True)
movie_message['电影id'] = movie_message.apply(lambda x:x['电影url'].replace('https://maoyan.com/films/',''),axis=1)
movie_message[['电影id']] = movie_message[['电影id']].apply(pd.to_numeric)
# 合并电影信息和票房
data = pd.merge(movie_box,movie_message,how='inner',on=['电影id'])
return data

# 只筛选中国的电影
data = data[data['国家'].str.contains('中国')]
# 剔除空值
data = data.dropna(subset=["导演/演员/编剧"])
# 将演员列表从字段“导演/演员/编剧”中分割出来
data['演员'] = data.apply(lambda x:x['导演/演员/编剧'] if '演员' in x['导演/演员/编剧'] else None,axis=1)
data['演员list'] = data.apply(lambda x:  ','.join(x['演员'].split('yyyyy')[1].split('xxxxx')[2:]) if pd.notnull(x['演员']) else None,axis=1)
# 剔除无演员列表的行
data = data.dropna(subset=["演员list"])
# 剔除无用字段
data.drop(['导演/演员/编剧'],axis=1,inplace=True)
data.drop(['演员'],axis=1,inplace=True)

因为考虑到配音类型的影片是看不到演员本人的,所以需要剔除配音类型影片。再将演员列表从行转置列,使得每行电影名称和演员是一一对应的。由于猫眼电影已经按照演员的出场频率进行排序,所以每部影片取前四名演员,作为影片主演,其中多明星合拍的影片,如《我和我的祖国》就改为取前十名。

# 拆分演员列表,并转置成一列
data = data.drop("演员list", axis=1).join(data["演员list"].str.split(",", expand=True).stack().reset_index(level=1, drop=True).rename("演员"))
# 剔除配音演员
data = data[~data['演员'].str.contains('配音')]
data['演员'] = data.apply(lambda x: x['演员'].split('饰:')[0] if '饰:' in x['演员'] else x['演员'], axis=1)
# 剔除分割演员名称错误的行
data = data[~data['演员'].str.contains('uncredited')]
data = data[~data['演员'].str.contains('voice')]
data = data[~data['演员'].str.contains('Protester')]
# 取每部电影的前四名演员,部分影片特殊
data_actor = data[['电影id','电影名称','演员']].drop_duplicates()
data_actor_top4 = data_actor[data_actor['电影名称']!='我和我的祖国'].groupby(['电影id','电影名称']).head(4)
data_actor_top10 = data_actor[data_actor['电影名称']=='我和我的祖国'].groupby(['电影id','电影名称']).head(10)
data_actor_top4 = pd.concat([data_actor_top4,data_actor_top10])
# 剔除外国演员
data_actor_top4['演员名字长度'] = data_actor_top4.apply(lambda x: len(x['演员']),axis=1)
data_actor_top4 = data_actor_top4[(data_actor_top4['演员名字长度']<=3)].copy()
data_actor_top4.drop("演员名字长度",axis = 1,inplace=True)
# 匹配
data = pd.merge(data,data_actor_top4,how='inner',on=['电影id','电影名称','演员'])

然后,拆分每部电影的电影题材类型并进行转置,再汇总每个演员出演过的电影题材,排序后取前三个类型,作为演员的拿手题材。

# 拆分电影题材
data = data.join(data["电影题材"].str.split(",",expand = True).stack().reset_index(level = 1,drop = True).rename("题材"))
# 取每位演员最擅长的电影题材TOP3
data_type_actor = data[['电影id','电影名称','演员','题材']].drop_duplicates().groupby(['演员', '题材']).agg({'电影id': 'count'}).reset_index().sort_values(['演员','电影id'],ascending=False)
data_type_actor = data_type_actor.groupby(['演员']).head(3)
data_type_actor = data_type_actor.groupby(['演员'])['题材'].apply(list).reset_index()
data_type_actor['题材'] = data_type_actor['题材'].apply(lambda x: ','.join(str(i) for i in list(set(x)) if str(i) != 'nan'))
data_type_actor.rename(columns={'题材': '演员_拿手题材'}, inplace=True)
data = pd.merge(data,data_type_actor,how='left',on=['演员'])

目前只有“演员总票房”和“影片平均评分”两个字段,可用作描述一个演员综合能力,所以需要衍生一些字段:

电影数量:统计演员主演过的影片数量;

大于10亿票房影片数量:汇总单部影片票房大于10亿的数量;

大于10亿票房影片计分:按照不同票房区间赋予分值,再汇总;

由于部分演员只出演过一部影片,属于单样本,若不剔除,会影响各项指标的数值分布。

actor = result[['演员','总票房','用户评分']].drop_duplicates()
# 衍生字段:平均票房、大于10亿票房影片、大于10亿票房影片计分
actor['用户评分'] = actor.apply(lambda x:0 if x['用户评分']=='暂无评分' else x['用户评分'],axis=1)
actor['大于10亿票房影片数量'] = actor.apply(lambda x:1 if x['总票房']>100000 else 0,axis=1)
# 按照票房赋予分值
def goal(x):
if x['总票房']<=100000:
division_goal = 0
elif x['总票房']<=200000:
division_goal = 1
elif x['总票房'] <= 300000:
division_goal = 2
elif x['总票房'] <= 400000:
division_goal = 3
elif x['总票房'] <= 500000:
division_goal = 4
else:
division_goal = 5
return division_goal
actor['大于10亿票房影片计分'] = actor.apply(goal,axis=1)
actor['电影数量'] = 1
actor['用户评分'] = pd.to_numeric(actor['用户评分'])
actor['大于10亿票房影片数量'] = pd.to_numeric(actor['大于10亿票房影片数量'])
actor['大于10亿票房影片计分'] = pd.to_numeric(actor['大于10亿票房影片计分'])
# 汇总
actor2 = actor.groupby(['演员']).agg({'总票房': 'sum',
'大于10亿票房影片数量': 'sum',
'大于10亿票房影片计分': 'sum',
'电影数量': 'count',
'用户评分':'mean',}).reset_index()
# 筛选影片数量大于1的行——只有一部影片的演员设为单样本,会影响标准化的结果
actor2 = actor2[actor2['电影数量']>1].reset_index(drop=True)

最后,由于数值字段之间的量纲不同,需要进行标准化处理后才可以进行比较。“演员总票房”的高低是衡量一个演员能力的重要因素,这里笔者将“大于10亿票房影片数量”和“大于10亿票房影片计分”也作为两点重要因素,而“影片平均评分”和“电影数量”作为次要因素,最终标准化处理后的计算公式:

总分=演员总票房+大于10亿票房影片数量+大于10亿票房影片计分+0.5*影片平均评分+0.5*电影数量

这里笔者曾用K-means聚类算法将演员划分为四个集群,通过查看集群的分布情况后发现,划分结果与上述公式计算后的总分排名情况十分相似(比如,总分1-20名划分成集群1,21-50名划分成集群2),所以取消了用聚类算法的方式划分演员档次。

# 复制一份副本
actor_copy = actor2.copy()
# 标准化处理
scaler = StandardScaler()
numeric_features = actor2.dtypes[actor2.dtypes != 'object'].index
scaler.fit(actor2[numeric_features])
scaled = scaler.transform(actor2[numeric_features])
for i, col in enumerate(numeric_features):
actor2[col] = scaled[:, i]
# 划分演员档次:权重求和,根据分值排序
result = actor2.apply(lambda x: x['总票房']+x['大于10亿票房影片数量']+x['大于10亿票房影片计分']+0.5*x['电影数量']+0.5*x['用户评分'],axis=1)
# # 划分演员档次——方法2:采用聚类算法,自动分成4个组
# actor_model = actor2[['总票房', '大于10亿票房影片数量', '大于10亿票房影片计分','电影数量','用户评分']].values
# y_pred = KMeans(n_clusters=4, random_state=9).fit_predict(actor_model)
# result2 = pd.Series(y_pred)
# 合并两种结果
model_actor_reuslt = pd.concat([actor_copy, result], axis=1)
model_actor_reuslt.rename(columns={0: '总分'},inplace=True)
model_actor_reuslt = model_actor_reuslt.sort_values('总分',ascending=False).reset_index(drop=True)

由于工作上经常使用BI工具tableau进行图表制作,因此下列的图表均用tableau绘制。其实pyecharts生成的图表也十分美观,为了方便这里就不用这个库画图了,有兴趣的小伙伴也可以了解下这个库。

先从整体上对电影的概况进行描述分析,才能更好地理解演员各项指标高低的优劣程度。首先,2011年至今,国内上映的影片总共是2129部,其中10亿票房以上的影片只有39部,占了总体的0.02%。

图1-1 电影总数

目前国内影片最高票房已经到50-60亿之间,只有一部。40-50亿只有两部,大部分10亿以上的票房都集中在10-20亿之间。

图1-2 电影票房区间

整体上,剧情、喜剧和爱情类型的电影题材拍得最多,而灾难类型的电影最少。从热门和冷门的电影题材中,很好地诠释了“报喜不报忧”这句成语,毕竟每个走进电影院的人都希望能轻松愉快地度过这两个小时。所以10亿以上票房的影片中,喜剧类型的电影题材反而排在了第一位。

图1-3 电影题材

从电影上映时间轴中可以看出,整体上,17年之前上映的影片逐年增加,但在17年之后有所下降。而10亿以上票房的影片每年都在增加,侧面说明近几年国内电影影片质量有所上升。

图1-4 电影上映时间轴

最后,将全部图表放到同一个仪表板中,可以很方便地看到10亿以上票房的影片分布情况,以及具体的影片名称。其中,2012年的《人在囧途之泰囧》是国内第一部10亿+票房影片,2015年的《捉妖记》是首部20亿+票房影片,2016年的《美人鱼》是首部30亿+票影片,2017年的《战狼2》是首部50亿+票房影片,而2019年的《流浪地球》和《哪吒之魔童降世》是唯一两部40亿+票房影片。从这个时间轴可以看出,自2015年起,每年最高票房都比前年多出10亿以上。

图1-5 电影概况

根据上述的计算公式得到总分TOP10的名单,前三名分别是黄渤、吴京和沈腾。这也难怪笔者的同学会对吴京出演的影片信心那么高。

图2-1 演员总分排名

汇总每个演员主演的电影票房后,得到总票房TOP10的名单,目前国内百亿票房均是男演员,分别是吴京、黄渤、杜江和沈腾。其中吴京已经是150亿票房冠军,而让笔者比较意想不到的是杜江也上了百亿榜,虽然他参演的几部热门影片,如《红海行动》、《我和我的祖国》和《中国机长》都不是第一主演,但这几部都是10亿+票房影片,是不是能说明他存在某些旺票房特质呢?

图2-2 演员总票房

再来看看演员电影数量TOP10的分布情况,可以看到前几名都是香港演员,其中古天乐在7年内主演了36部影片,位列榜首。除了影片数量位列榜首外,其实平平无奇的古仔已经默默地捐赠了100多所学校,这也许就是他当上电影“劳模”的原因吧。

图2-3 演员电影数量

最后,将上述三张图表和详细列表放到同个仪表板中,就可以清楚地知道,能够位列前茅的演员都是主演过多部影片,并且拥有多部10亿+票房影片。其中有一个比较有趣的地方是王宝强的影片平均评分是6.3,但他仍然能够排到第七名,原因是他主演过几部评分在5分以下的影片,才导致他平均评分会这么低。

图2-4 演员概况

本文旨在让大家了解一下国内电影的整体概况和演员概况,所以只是简单地对数据进行描述性分析,并没有运用到机器学习这方面的知识。一般地,描述性分析是做数据分析必不可少的一步,通过简单的几个图表就能直观地对数据有整体上的认知。最后也要谢谢同事Yan姐的一些指导。

作者简介:AJ-Gordon,数据分析师一枚,对爬虫、机器学习、数据可视化、数据建模均有所涉猎。

声明:  本文为作者原创投稿,未经允许请勿转载。

【END】

给IT届的小白们准备的一套python爬虫路线+学习教程

https://edu.csdn.net/topic/python115?utm_source=csdn_bw

热 文 推 荐

640?wx_fmt=gif 点击阅读原文 ,参与中国开发者现状调查问卷!

作者 | AJ-Gordon责编 | 刘静出品 | CSDN(ID:CSDNnews)项目背景上个月笔者的一个同学开了间影视投资公司,出于对创业人员的仰慕和影视投资行业的好奇,我就跟他寒暄了几句,聊天当中他提及到国庆节有部《攀登者》即将上映,预计票房会大好,因为吴京是这部片的主演。然后我就想,目前吴京在国内演员中位列几何呢?正好之前爬了猫眼电影数据,... 在应用 python 词云前,需要一些必要的准备工作 第一,我们需要知道 python 词云是什么? python 词云是用字体的大小展示数据应用次数多少的工具,字体越大,代表着数据应用次数越多,反之亦然。 下面图片大家感受一下 在数据 分析 中,我们常用词云来 分析 群众对一个事物的印象 比如第一张图片中,对西安的印象第一眼最明显的就是西安和兵马俑,用词云将数据可视化能够使数...
电影是现在大家非常喜爱的一个娱乐产品,然而,不同电影的票房是不一样的。假设已经用爬虫爬取到了一定数据,现在用 Python 做数据 分析 ,来观测不同电影之间的票房差距。代码和结果如下: from matplotlib import pyplot as plt import matplotlib font = { ‘family’:‘SimHei’, ‘weight’:‘bold’, ‘size’:12 matplotlib.rc(“font”, **font) plt.figure(figsize=(10,7
1.编写 Mapper类,将数据集解析为 key=gender,value=name+hotIndex,然后输出。 2.编写 Combiner 类,合并 Mapper 输出结果,然后输出给 Reducer。 3.编写 Partitioner 类,按性别,将结果指定给不同的 Reduce 执行。 上个月笔者的一个同学开了间影视投资公司,出于对创业人员的仰慕和影视投资行业的好奇,我就跟他寒暄了几句,聊天当中他提及到国庆节有部《攀登者》即将上映,预计票房会大好,因为吴京是这部片的主演。然后我就想,目前吴京在国内 演员 中位列几何呢?正好之前爬了猫眼电影数据,基于 python 数据 分析 的方式, 分析 中国 演员 排名 情况。 导入之前爬取到的猫眼数据,由于爬取过程不是本文的主要内容,所以简单描述下数据情况:20110101至20191019年在 中国 上映,并且有用户评分和票房的影片,总..
文章目录1. KMeans in Sklearn2. Sklearn 实例:电影评分的 k 均值聚类2.1 数据集概述2.2 二维 KMeans 聚类3. 肘部法选取最优 K 值4. 多维 KMeans 聚类4.1 三维 KMeans 聚类4.2 高维 KMeans 聚类4.2.1 热力图可视化4.2.2 稀疏 csr 矩阵4.2.3 利用聚类结果进行预测4.2.4 利用聚类结果进行推荐 相关文章...
初学数据 分析 ,这次就来 分析 一下电影信息。豆瓣电影的实战项目网上文章也不少,不过还是要自己操作一下才能理解得更深刻一点,也顺便了解一下这些电影的特点。。 项目涉及的是一个特殊的电影排行榜,能上榜的想必都是非常受欢迎的电影,毕竟豆瓣上的评分还有热度都是很有参考性的。所以在这里对这个排行榜的排列标准探索一下,当然也只是粗略地 分析 。 豆瓣用户每天都在对“看过”的电影进行“很差”到“力荐”的评价,豆瓣根据每...
想关注你的爱豆最近在娱乐圈发展的怎么样吗?本文和你一起爬取娱乐圈的排行榜数据,来看看你的爱豆现在 排名 变化情况,有几次登顶,几次进了前十名呀。 一、网站原始信息 我们先来看下原始的网站页面 如果我们想一个一个复制这些数据,再进行 分析 ,估计要花一天的时间,才可以把明星的各期排行数据处理好。估计会处理到崩溃,还有可能会因为人为原因出错。 而用爬虫,半个小时不到就可以处理好这些数据。接下来看看怎么把这些数据用 Python 爬下来吧。 二、先来看下爬取后数据的部分截图 1 男明星人气榜数据 2 女明星人气榜数据
TEF668X (‘Lithio’) is a series of novel single-chip car radio devices with an upper mainstream to high-end performance and feature set. This user manual describes the TEF668X series control interface or API (Application Programming Interface). The document describes the available write and read commands with parameter and data definitions. This document version contains limited background information regarding the feature functionality and the offered control options