0


Python案例实操3-电影数据分析

Python案例实操3-电影数据分析

本案例数据来源于 kaggle 上的
Movie数据集,主要研究以下几个问题:

  1. 电影类型如何随着时间的推移发生变化的?
  2. 统计电影分类的情况?
  3. 电影类型与利润的关系?
  4. Universal 和 Paramount 两家影视公司的对比情况如何?
  5. 改编电影和原创电影的对比情况如何?
  6. 电影时长与电影票房及评分的关系?
  7. 分析电影关键字

实战开始:

一、读取数据

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: objectprint('缺失电影时长的电影名称为:\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 格式defdata_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.电影类型随时间变化趋势图

在这里插入图片描述

思路

  1. 在每行数据后追加所有电影类型列,初始值为0
  2. 遍历每一部电影的’genres’列,把分类包含在该列中的值置为1
  3. 分组并按照类型求和在这里插入图片描述
# 将 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:# 先增加所有电影类型列,初始值为0
    datalist.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中把分类出现的列的值置为1for i inrange(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_profit
    movie_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, STOPWORDS

keywords_list =[]for x in datalist['keywords']:
        keywords_list.append(x)
    str_key =''.join(keywords_list)
    str_key.replace('\'s','')# 设置停用词
    stopwords = STOPWORDS
    stopwords.update(['based','film'])# 封装词云
    wc = WordCloud(
        background_color="white",
        font_path="simkai.ttf",# 字体 C:\Windows\Fonts
        stopwords=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


本文转载自: https://blog.csdn.net/weixin_45698637/article/details/122777579
版权归原作者 Buckletime 所有, 如有侵权,请联系我们删除。

“Python案例实操3-电影数据分析”的评论:

还没有评论