Python数据分析:整理Netflix演员电影评分项目实战

📅 发布时间:2026/7/6 7:01:13 👁️ 浏览次数:
Python数据分析:整理Netflix演员电影评分项目实战
Netflix数据揭秘谁是各流派评分之王大家好最近我完成了一个有趣的数据分析实战项目——整理Netflix电影和电视剧的演员评分数据最终挖掘出各个流派中平均IMDB评分最高的演员。今天我就严格按照项目笔记的流程把完整的数据清洗、整理、分析过程分享给大家希望能给同样对数据感兴趣的小伙伴一些启发 分析目标此数据分析的目的是整理不同流派影视作品比如喜剧片、动作片、科幻片中各演员出演作品的平均IMDB评分从而挖掘出各个流派中的高评分作品演员。本实战项目的目的在于练习整理数据从而得到可供下一步分析的数据。 数据集简介原始数据集记录了截止至2022年7月美国地区可观看的所有Netflix电视剧及电影数据。数据集包含两个数据表titles.csv和credits.csv。titles.csv包含电影及电视剧相关信息每列含义如下id影视作品IDtitle影视作品标题type作品类型电视节目SHOW或电影MOVIEdescription简短描述release_year发布年份age_certification适龄认证runtime每集或电影的长度分钟genres流派类型列表字符串形式的列表production_countries出品国家列表字符串形式的列表seasons如果是电视剧则是季数imdb_idIMDB的IDimdb_scoreIMDB评分imdb_votesIMDB投票数tmdb_popularityTMDB流行度tmdb_scoreTMDB评分credits.csv包含演职员信息每列含义如下person_id演职员IDid参与的影视作品IDname姓名character角色姓名role演职员类型ACTOR演员或DIRECTOR导演 读取数据首先导入数据分析所需的库——Pandas并通过read_csv函数将两个原始数据文件读入DataFrame。import pandas as pd original_titles pd.read_csv(titles.csv) original_credits pd.read_csv(credits.csv)查看前几行数据确认读取成功original_titles.head()idtitletypedescriptionrelease_yearage_certificationruntimegenresproduction_countriesseasonsimdb_idimdb_scoreimdb_votestmdb_popularitytmdb_scorets300399Five Came Back: The Reference...SHOWThis collection includes 12 World War II-era p...1945TV-MA51[documentation][US]1.0NaNNaNNaN0.600NaNtm84618Taxi DriverMOVIEA mentally unstable Vietnam War veteran works ...1976R114[drama, crime][US]NaNtt00753148.2808582.040.9658.179tm154986DeliveranceMOVIEIntent on seeing the Cahulawassee River before...1972R109[drama, action, thriller, european][US]NaNtt00684737.7107673.010.0107.300tm127384Monty Python and the Holy GrailMOVIEKing Arthur, accompanied by his squire, recrui...1975PG91[fantasy, action, comedy][GB]NaNtt00718538.2534486.015.4617.811tm120801The Dirty DozenMOVIE12 American military prisoners in World War II...1967NaN150[war, action][GB, US]NaNtt00615787.772662.020.3987.600original_credits.head()person_ididnamecharacterrole3748tm84618Robert De NiroTravis BickleACTOR14658tm84618Jodie FosterIris SteensmaACTOR7064tm84618Albert BrooksTomACTOR3739tm84618Harvey KeitelMatthew Sport HigginsACTOR48933tm84618Cybill ShepherdBetsyACTOR 评估和清理数据为了区分原始数据和清洗后的数据我们先创建两个副本cleaned_titles original_titles.copy() cleaned_credits original_credits.copy() 数据整齐度从cleaned_titles的前10行可以看出genres和production_countries列中包含多个值以列表形式存储但实际上它们是字符串需要拆分成多行。查看genres列的第一个值cleaned_titles[genres][1]输出[drama, crime]字符串使用eval函数将字符串转换为真正的列表cleaned_titles[genres] cleaned_titles[genres].apply(lambda s: eval(s)) cleaned_titles[genres][1]输出[drama, crime]列表然后用explode将列表拆成多行cleaned_titles cleaned_titles.explode(genres) cleaned_titles.head(10)此处显示拆分行后的结果原本一行变成多行同样的操作也应用于production_countries列cleaned_titles[production_countries] cleaned_titles[production_countries].apply(lambda s: eval(s)) cleaned_titles cleaned_titles.explode(production_countries)查看cleaned_credits的前10行结构已经很整齐无需进一步拆分。 数据干净度通过info()了解数据的基本情况cleaned_titles.info()输出显示共有17818条记录多个列存在缺失值如title缺失1条、description缺失28条、age_certification缺失较多、genres缺失63条、production_countries缺失379条、seasons缺失很多、imdb_score缺失842条等。另外release_year是整数应该转换为日期类型cleaned_titles[release_year] pd.to_datetime(cleaned_titles[release_year], format%Y)对于cleaned_creditscleaned_credits.info()输出显示有77801条记录character列存在缺失值约9772条缺失person_id是整数应转为字符串cleaned_credits[person_id] cleaned_credits[person_id].astype(str)处理缺失数据分析所需的核心数据是imdb_score和genres缺失这些值会影响分析因此需要删除。查看imdb_score缺失的观察值cleaned_titles.query(imdb_score.isnull())共有842行缺失删除它们cleaned_titles cleaned_titles.dropna(subset[imdb_score]) cleaned_titles[imdb_score].isnull().sum() # 输出0查看genres缺失的观察值cleaned_titles.query(genres.isnull())共有6行缺失删除cleaned_titles cleaned_titles.dropna(subset[genres]) cleaned_titles[genres].isnull().sum() # 输出0cleaned_credits中character缺失不影响分析保留。处理重复数据检查两个DataFrame是否有完全重复的行cleaned_titles.duplicated().sum() # 输出0 cleaned_credits.duplicated().sum() # 输出0均无重复。处理不一致数据查看genres列的值分布cleaned_titles[genres].value_counts()输出显示所有流派名称都是统一的没有不一致。但存在空字符串需要删除cleaned_titles cleaned_titles.query(genres ! ) cleaned_titles.query(genres ) # 空DataFrame查看production_countries列的值分布cleaned_titles[production_countries].value_counts()由于国家代码较多可以临时设置显示所有行with pd.option_context(display.max_rows, None): print(cleaned_titles[production_countries].value_counts())发现有一个值Lebanon而标准国家代码应为LB属于不一致。将其统一替换为LBcleaned_titles[production_countries] cleaned_titles[production_countries].replace({Lebanon: LB})再次检查确认Lebanon已不存在。查看original_credits中role列的值分布original_credits[role].value_counts()只有ACTOR和DIRECTOR两种没有不一致。为了方便将其转换为category类型cleaned_credits[role] cleaned_credits[role].astype(category)处理无效或错误数据使用describe()查看数值列的统计信息确保没有超出合理范围的数值original_titles.describe()从输出看runtime最小为0可能有问题但暂不处理imdb_score范围1.5~9.6imdb_votes范围5~229万都在合理范围内。 整理数据现在数据已经清洗完毕我们需要将titles和credits合并以便同时获取影视作品信息和演员信息。合并两个DataFrame通过id影视作品ID进行内连接credits_with_titles pd.merge(cleaned_credits, cleaned_titles, onid, howinner)合并后我们就能知道每个演职员参与过的影视作品的具体信息。筛选演员由于我们只关心演员不关心导演所以筛选role ACTORactor_with_titles credits_with_titles.query(role ACTOR)分组计算平均IMDB评分我们需要按流派和演员分组计算每个演员在每个流派下的平均评分。注意分组时使用person_id而不是name因为名字可能有重复或拼写错误。groupby_genres_and_person_id actor_with_titles.groupby([genres, person_id])提取imdb_score并计算均值imdb_score_groupby_genres_and_person_id groupby_genres_and_person_id[imdb_score].mean()结果是一个多层索引的Series可以重置索引变成规整的DataFrameimdb_score_groupby_genres_and_person_id_df imdb_score_groupby_genres_and_person_id.reset_index()此时我们得到了每个演员在每个流派下的平均IMDB评分。 挖掘各流派评分之王为了找出每个流派中平均评分最高的演员我们需要再次按流派分组求出最高分genres_max_scores imdb_score_groupby_genres_and_person_id_df.groupby(genres)[imdb_score].max()输出各流派的最高平均分genres action 9.3 animation 9.3 comedy 9.2 crime 9.5 documentation 9.1 drama 9.5 european 8.9 family 9.3 fantasy 9.3 history 9.1 horror 9.0 music 8.8 reality 8.9 romance 9.2 scifi 9.3 sport 9.1 thriller 9.5 war 8.8 western 8.9 Name: imdb_score, dtype: float64接下来将最高分与原始分组表合并得到每个流派最高分对应的演员IDgenres_max_score_with_person_id pd.merge(imdb_score_groupby_genres_and_person_id_df, genres_max_scores, on[genres, imdb_score])结果可能有多行因为一个流派可能有多个演员并列最高分。为了得到演员名字我们需要从cleaned_credits中提取唯一的person_id和name对应关系actor_id_with_names cleaned_credits[[person_id, name]].drop_duplicates()然后合并genres_max_score_with_actor_name pd.merge(genres_max_score_with_person_id, actor_id_with_names, onperson_id)最后按流派排序并重置索引让结果更清晰genres_max_score_with_actor_name genres_max_score_with_actor_name.sort_values(genres).reset_index().drop(index, axis1) 最终成果各流派高分演员榜以下是整理后的最终结果共136行展示部分genresperson_idimdb_scorenameaction127909.3Olivia Hackaction13039.3Jessie Floweraction210339.3Zach Tyleraction3368309.3André Sogliuzzoaction865919.3Cricket Leighanimation1001449.3Tom Hankscomedy115149.2John Doecrime203459.5Robert De Nirodrama37489.5Robert De Niro............war8265478.8Yuto Uemurawestern281808.9Unsho Ishizukawestern223118.9Koichi Yamaderawestern281668.9Megumi Hayashibarawestern930178.9Aoi Tada有趣发现动作片最高分9.3由多位配音演员获得他们很可能参与了一些高分动画电影。犯罪片和剧情片的最高分9.5均被罗伯特·德尼罗拿下不愧是老戏骨战争片最高分8.8西部片最高分8.9还有提升空间。 资源获取在公众号后台回复关键词「Netflix演员电影评分」即可获取本项目的数据文件titles.csv 和 credits.csv以及完整的 Jupyter Notebook 代码文件方便你动手实践 总结与反思通过这个项目我们完整地实践了数据清洗、整合、分组聚合的全流程最终得到了每个流派中平均IMDB评分最高的演员名单。当然本次分析还可以进一步深化样本量过滤有些演员可能只出演了一两部作品平均分可能受极端值影响后续可以加入“至少出演n部”的条件。结合其他因素可以结合投票数、年份等进一步分析比如近十年活跃演员的评分趋势。可视化可以用图表展示各流派最高分分布或演员评分对比。希望这篇详细的笔记能帮助到正在学习数据分析的你如果你有任何问题或想法欢迎留言交流 本文使用的数据集来源于Netflix公开数据仅用于学习交流。