如何通过 Python 分析中国演员排名?

电影快讯 1171℃
如何通过 Python 分析中国演员排名? - 陆剧吧

作者 | AJ-Gordon

如何通过 Python 分析中国演员排名? - 陆剧吧

项目背景

上个月笔者的一个同学开了间影视投资公司,出于对创业人员的仰慕和影视投资行业的好奇,我就跟他寒暄了几句,聊天当中他提及到国庆节有部《攀登者》即将上映,预计票房会大好,因为吴京是这部片的主演。 然后我就想,目前吴京在国内演员中位列几何呢? 正好之前爬了猫眼电影数据,基于python数据分析的方式,分析中国演员排名情况。

如何通过 Python 分析中国演员排名? - 陆剧吧

数据导入

导入之前爬取到的猫眼数据,由于爬取过程不是本文的主要内容,所以简单描述下数据情况: 20110101至20191019年在中国上映,并且有用户评分和票房的影片,总共是2923部。

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(, '' ),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(lambdax:x[ '导演/演员/编剧' ] if '演员' in x[ '导演/演员/编剧' ] else None,axis= 1 ) data [ '演员list' ]= data .apply(lambdax: ',' .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(lambdax: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(lambdax: 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(lambdax: ',' .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]) fori,colinenumerate(numeric_features): actor2[col]=scaled[:,i] #划分演员档次:权重求和,根据分值排序 result=actor2.apply(lambdax: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】

热 文 推 荐

☞ iPhone11因便宜销量超预期;三星手机曝高危漏洞;xUtils 3.8.3发布 | 极客头条

☞ 前Facebook面试官告诉你如何才能顺利通过编程面试

☞ 软件核心研发迎来又一春!

☞ 华为负重疾行

☞ 为何Google、微软、华为将亿级源代码放一个仓库?从全球最大代码管理库说起

☞ 计算机专业的学生也太太太太太惨了吧?

☞ BTC 固定的货币政策,真的无懈可击吗?

标签: 电影快讯