Python数据分析实战:TMDB电影数据可视化 |
您所在的位置:网站首页 › 数据分析实战网站哪个好点 › Python数据分析实战:TMDB电影数据可视化 |
出品:Python数据之道 (ID:PyDataLab) 作者:叶庭云 编辑:Lemon 一、数据预处理本文将以项目实战的形式,对 TMDB电影数据进行数据分析与可视化实战,所使用的数据来源于 Kaggle,文末提供数据的下载方式。 import json import pandas as pd import numpy as np from datetime import datetime import warnings warnings.filterwarnings('ignore') # 不显示告警信息 # 读取电影数据 指定引擎 不然会报错误 df = pd.read_csv('tmdb_5000_movies.csv', engine='python') df.head() # 由于数据集中包含的信息过多,其中部分数据并不是我们研究的重点,所以从中抽取分析要用的数据: # 关键词 电影名称 电影类型 首次上映日期 电影时长 预算 收入 df1 = df[['keywords', 'original_title', 'genres', 'release_date', 'runtime', 'budget', 'revenue', 'vote_count', 'vote_average']] df1.info() # 方法二 查阅资料 填充缺失数据 # IMDb官网 https://www.imdb.com/title/tt3856124/ df1.loc[2656, 'runtime'] = 98.0 df1.loc[4140, 'runtime'] = 81.0 df1.loc[4553, 'release_date'] = '2014-06-01' df1.info() # genres列数据处理 df1['genres'].head() # 将str转换为json df1['genres'] = df1['genres'].apply(json.loads) def decode(col): genre = [] for item in col: genre.append(item['name']) return '|'.join(genre) df1['genres'] = df1['genres'].apply(decode) df1.head() # 提取release_date的年份 df1['release_date'] = pd.to_datetime(df1['release_date']).dt.year # 改列的名称 col = {'release_date': 'year'} df1.rename(columns=col, inplace=True) df1['year'].apply(int).head() # 转为整数 # 保存为已清洗数据 df1.to_excel('已清洗数据.xlsx') 二、数据分析 1. 建立包含年份与电影类型数量的关系数据框各类型电影的数量如何随着时间的推移发生变化的?建立包含年份与电影类型数量的关系数据框 提取取2000-2017年的各电影类型数量 热力图可视化 """ @Author :叶庭云 @Date :2020/10/2 11:40 """ import pandas as pd import matplotlib.pyplot as plt import matplotlib as mpl import seaborn as sns # 读取Excel数据 df = pd.read_excel('已清洗数据.xlsx') # 有个别行数据清洗时不是nan 但为空列表 提取后为nan df.dropna(inplace=True) # 建立genres列表,提取电影的类型 genres_set = set() for genre in df['genres'].str.split('|'): for item in genre: genres_set.add(item) genres_list = list(genres_set) for genre in genres_list: # 判断每行 有这个类型 对应类型的列下添个1 df[genre] = df['genres'].str.contains(genre).apply(lambda x: 1 if x else 0) genre_year = df.loc[:, genres_list] # 将年份作为索引标签 genre_year.index = df['year'] # 将数据集按年份分组并求和,得出每个年份,各电影类型的电影总数 genresdf = genre_year.groupby('year').sum() # 包含年份与电影类型数量的DataFrame print(genresdf) # 取2000-2016年的电影类型数量 热力图可视化 17年数据就没几部 datas = genresdf.iloc[-18:-1:1, ::] mpl.rcParams['font.family'] = 'Kaiti' fig, ax = plt.subplots(figsize=(15, 9)) print(datas) # 绘制热力图 cmap:从数字到色彩空间的映射 sns.heatmap(data=datas.T, linewidths=0.25, linecolor='white', ax=ax, annot=True, fmt='d', cmap='Accent', robust=True, ) # 添加描述信息 x y轴 title ax.set_xlabel('年份', fontdict={'size': 18, 'weight': 'bold'}) ax.set_ylabel('电影类型', fontdict={'size': 18, 'weight': 'bold'}) ax.set_title(r'2000-2016年各电影类型数量', fontsize=25, x=0.5, y=1.02) # 隐藏边框 ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) ax.spines['left'].set_visible(False) ax.spines['bottom'].set_visible(False) # 保存 展示图片 plt.savefig('heat_map.png') plt.show()从热力图可以直观分析出,Drama 和 Comedy 每年的电影数量都比较多,Thriller每年的电影数量也比较可观。 2. 数量最多的电影类型Top10 """ @Author :叶庭云 @Date :2020/10/2 11:40 """ import pandas as pd import matplotlib.pyplot as plt import matplotlib as mpl # 读取数据 df = pd.read_excel('已清洗数据.xlsx') # 有个别行提取类型时不是nan 但为空列表 再提取后为nan df.dropna(inplace=True) # 建立genres列表,提取电影的类型 genres_set = set() for genre in df['genres'].str.split('|'): for item in genre: genres_set.add(item) genres_list = list(genres_set) for genre in genres_list: # 判断每行 有这个类型 对应类型的列下添个1 df[genre] = df['genres'].str.contains(genre).apply(lambda x: 1 if x else 0) genre_year = df.loc[:, genres_list] # 将年份作为索引标签 genre_year.index = df['year'] # 将数据集按年份分组并求和,得出每个年份,各电影类型的电影总数 genresdf = genre_year.groupby('year').sum() genres_count = genresdf.sum(axis=0).sort_values(ascending=False) # 升序 # print(genres_count.index) # print(genres_count.values) colors = ['#FF0000', '#FF1493', '#00BFFF', '#9932CC', '#0000CD', '#FFD700', '#FF4500', '#00FA9A', '#191970', '#006400'] # 设置大小 像素 plt.figure(figsize=(12, 8), dpi=100) # 设置中文显示 mpl.rcParams['font.family'] = 'SimHei' plt.style.use('ggplot') # 绘制柱形图 设置柱条的宽度和颜色 plt.barh(genres_count.index[9::-1], genres_count.values[9::-1], height=0.6, color=colors[::-1]) plt.xlabel('电影数量', fontsize=12) plt.ylabel('电影类型', fontsize=12, color='red') plt.title('数量最多的电影类型Top10', fontsize=18, x=0.5, y=1.05) plt.savefig('test_001.png') plt.show()电影数量最多的电影类型前五为:Drama(戏剧)、Comedy(喜剧)、Thriller(惊悚)、Action(动作)、Romance(浪漫) 3. 各种电影类型所占比例 """ @Author :叶庭云 @Date :2020/10/2 11:40 """ import pandas as pd import matplotlib.pyplot as plt import matplotlib as mpl df = pd.read_excel('已清洗数据.xlsx') # 有个别行提取类型时不是nan 但为空列表 提取后为nan df.dropna(inplace=True) # 建立genres列表,提取电影的类型 genres_set = set() for genre in df['genres'].str.split('|'): for item in genre: genres_set.add(item) genres_list = list(genres_set) for genre in genres_list: # 判断每行 有这个类型 对应类型的列下添个1 df[genre] = df['genres'].str.contains(genre).apply(lambda x: 1 if x else 0) genre_year = df.loc[:, genres_list] # 将年份作为索引标签 genre_year.index = df['year'] # 将数据集按年份分组并求和,得出每个年份,各电影类型的电影总数 genresdf = genre_year.groupby('year').sum() genres_count = genresdf.sum(axis=0).sort_values(ascending=False) # 升序 # print(genres_count.index) # print(genres_count.values) # print(len(genres_count.values)) # 设置中文显示 mpl.rcParams['font.family'] = 'SimHei' # 设置大小 像素 plt.figure(figsize=(12, 8), dpi=100) plt.axes(aspect='equal') # 保证饼图是个正圆 explodes = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.1, 0.25, 0.4, 0.55, 0.7, 0.85] plt.pie(genres_count.values, labels=genres_count.index, autopct='%.2f%%', shadow=True, explode=explodes, startangle=15, labeldistance=1.1, ) plt.title('各种电影类型所占比例', fontsize=18) plt.savefig('test_002.png') plt.show()在所有的电影类型中,Drama(戏剧)类型电影最多,占比高达18.89%,其次为Comedy(喜剧),占比14.16%。 4. 电影关键词分析 """ @Author :叶庭云 @Date :2020/10/2 11:40 """ import pandas as pd import collections from wordcloud import WordCloud import matplotlib.pyplot as plt df = pd.read_csv('tmdb_5000_movies.csv')['keywords'] key_words_list = [] for item in df: item = eval(item) if item: # 为空列表 滤掉 # ['aftercreditsstinger', 'duringcreditsstinger'] 这个词语频率比较高 但好像没啥意义 滤掉 key_words_list.extend([x['name'] for x in item if x['name'] not in ['aftercreditsstinger', 'duringcreditsstinger']]) words_count = collections.Counter(key_words_list) print(words_count) wc = WordCloud( background_color='white', max_words=2000, max_font_size=100, random_state=8, ) wc.generate_from_frequencies(words_count) plt.imshow(wc) plt.axis('off') plt.savefig('test_003.png') plt.show()通过对电影关键字的词云图分析,可以发现电影中经常被提及的关键词是女性(woman)、独立(independent),其次是谋杀(murder)、暴力(violence)、复仇(revenge)、基于小说(based on novel),可见观众对女性和独立方面题材的电影最感兴趣,其次是犯罪类和基于小说改编的电影。 5. 各类型电影数量随时间变化趋势 """ @Author :叶庭云 @Date :2020/10/2 11:40 """ import pandas as pd import matplotlib.pyplot as plt import matplotlib as mpl # 读取数据 df = pd.read_excel('已清洗数据.xlsx') # 有个别行提取类型时不是nan 但为空列表 提取后为nan df.dropna(inplace=True) # 建立genres列表,提取电影的类型 genres_set = set() for genre in df['genres'].str.split('|'): for item in genre: genres_set.add(item) genres_list = list(genres_set) for genre in genres_list: # 判断每行 有这个类型 对应类型的列下添个1 df[genre] = df['genres'].str.contains(genre).apply(lambda x: 1 if x else 0) genre_year = df.loc[:, genres_list] # 将年份作为索引标签 genre_year.index = df['year'] # 将数据集按年份分组并求和,得出每个年份,各电影类型的电影总数 genresdf = genre_year.groupby('year').sum() print(genresdf) # 设置中文显示 mpl.rcParams['font.family'] = 'SimHei' # 设置大小 像素 plt.figure(figsize=(10, 6), dpi=100) # 设置图形显示风格 plt.style.use('ggplot') # DataFrame 绘制折线图 plt.plot(genresdf, label=genresdf.columns) # 添加描述信息 plt.xticks(range(1915, 2018, 5)) plt.xlabel('年份', fontsize=12) plt.ylabel('电影数量', fontsize=12) plt.title('各电影类型的数量随时间变化趋势', fontsize=18, x=0.5, y=1.02) # 显示图例 plt.legend(genresdf) # 保存图片 plt.savefig('test_004.png') # 展示图片 plt.show()从折线图图中容易发现,随着时间的推移,所有电影类型都呈现出增长趋势,大概在1992年以后各类型的电影均增长迅速,可能原因为人们物质生活水平提高,对观影有了更多需求,其中Drama(戏剧)和Comedy(喜剧)增长最快,目前仍是最热门的电影类型。 6. 电影票房与电影时长关系 """ @Author :叶庭云 @Date :2020/10/2 11:40 """ import pandas as pd import matplotlib as mpl import matplotlib.pyplot as plt # 读取数据 df = pd.read_excel('已清洗数据.xlsx') # 电影时长 票房 run_time, revenue = df['runtime'], df['revenue'] # 设置中文显示 mpl.rcParams['font.family'] = 'SimHei' # 设置图形显示风格 plt.style.use('ggplot') # 设置大小 像素 plt.figure(figsize=(9, 6), dpi=100) # 绘制散点图 plt.scatter(run_time, revenue) # 添加描述信息 plt.title('电影票房与电影时长的关系', fontsize=18, x=0.5, y=1.02) plt.xlabel('电影时长(分钟)') plt.ylabel('电影票房(亿美元)') # 保存图片 plt.savefig('test_005.png') # 显示图片 plt.show() 7. 电影平均评分与电影时长关系 """ @Author :叶庭云 @Date :2020/10/2 11:40 @CSDN :https://blog.csdn.net/fyfugoyfa """ import pandas as pd import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np # 读取数据 df = pd.read_excel('已清洗数据.xlsx') # 提取电影时长 平均评分 run_time, rating_score = df['runtime'], df['vote_average'] # 设置中文显示 mpl.rcParams['font.family'] = 'SimHei' # 设置图形显示风格 plt.style.use('ggplot') # 设置大小 像素 plt.figure(figsize=(9, 6), dpi=100) # 绘制散点图 plt.scatter(run_time, rating_score, c='purple') plt.yticks(np.arange(0, 10.5, 1)) # 添加描述信息 plt.title('电影平均评分与电影时长的关系', fontsize=18, x=0.5, y=1.02) plt.xlabel('电影时长(分钟)') plt.ylabel('平均评分') # 保存图片 plt.savefig('test_006.png') # 显示图片 plt.show()从两幅散点图可以看出,电影要想获得较高的票房及良好的口碑,电影的时长应保持在 100-150 分钟内较好。 作者简介: 叶庭云 个人格言: 热爱可抵岁月漫长 CSDN 博客: https://blog.csdn.net/fyfugoyfa/ 本文数据获取方式 本文数据可以通过下述步骤来获取: 1. 扫描下方二维码 2. 回复关键词:电影 (建议复制关键词) ????长按上方二维码 2 秒 回复「电影」即可获取资料 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |