zoukankan      html  css  js  c++  java
  • 观影大数据分析(中)

    数据分析

    why

    想要探索影响票房的因素,从电影市场趋势,观众喜好类型,电影导演,发行时间,评分与 关键词等维度着手,给从业者提供合适的建议。

    what

    电影类型:定义一个集合,获取所有的电影类型

    # 获取电影类型
    
    genre_list = set()
    for i in df['genres'].str.split(','):
        genre_list = set().union(i, genre_list)
    
    print(genre_list)
    

    注意到集合中存在多余的元素:空的单引号,所以需要去除

    # 去除多余元素
    genre.discard('')
    

    电影类型数量(绘制条形图)

    type_num = genre_df.sum().sort_values(ascending = False)
    bar_x = type_num.index
    bar_y = type_num
    
    # 设置matplotlib正常显示中文和负号
    plt.rcParams['font.sans-serif']=['SimHei']   # 用黑体显示中文
    plt.rcParams['axes.unicode_minus']=False     # 正常显示负号
    
    plt.figure(figsize= (15, 8), dpi = 80)
    plt.bar(bar_x, bar_y)
    
    # 设置x轴
    plt.xlabel('电影类型')
    plt.ylabel('数量')
    plt.show()
    

    电影类型占比(绘制饼图)

    type_proportion = type_num / type_num.sum()
    
    # 可视化
    plt.figure(figsize=(15, 8), dpi = 80)
    
    # 设置matplotlib正常显示中文和负号
    plt.rcParams['font.sans-serif'] = ['SimHei']   # 用黑体显示中文
    plt.rcParams['axes.unicode_minus'] = False     # 正常显示负号
    
    pie_x = type_proportion[type_proportion > 0]
    pie_labels = type_proportion[type_proportion > 0].index
    explode = (pie_x < 0.05) / 5
    plt.pie(pie_x, labels = pie_labels, explode = explode)
    plt.title('电影类型占比', fontsize = 20)
    plt.show()
    

    电影类型变化趋势(绘制折线图)

    # 增加一列。发布年份
    genre_df['year'] = df['release_year']
    
    # 将年份作为索引值
    genre_df.set_index('year')
    
    # 根据年份分类
    genre_year_sum = genre_df.groupby('year').sum()
    plt.figure(figsize = (25, 12), dpi = 80)
    plt.plot(genre_year_sum)
    
    plt.legend(genre_year_sum.columns, fontsize = 15)
    
    plt.title("电影类型变化趋势", fontsize = 20)
    plt.xlabel("年份")
    plt.ylabel("电影数量")
    
    plt.show()
    

    不同电影类型预算/利润(绘制组合图)

    df['profit'] = df['revenue'] - df['budget']
    
    # 计算不同电影类型的利润
    
    # Step1-创建profit_dataframe
    profit_df = pd.DataFrame()
    
    profit_df = pd.concat([genre_df.reset_index(), df['profit']], axis=1)
    
    # Step2-创建profit_series,横坐标为genre
    profit_s=pd.Series(index=genre_list)
    
    # Step3-求出每种genre对应的利润均值
    for i in genre_list:
        profit_s.loc[i]=profit_df.loc[:,[i,'profit']].groupby(i, as_index=False).mean().loc[1,'profit']
    profit_s = profit_s.sort_values(ascending = True)
    
    profit_s
    
    # 计算不同类型电影的budget
    # Step1-创建profit_dataframe
    budget_df = pd.DataFrame()
    budget_df = pd.concat([genre_df.reset_index(), df['budget']], axis=1)
    
    # Step2-创建budget_series,横坐标为genre
    budget_s=pd.Series(index=genre_list)
    
    # Step3-求出每种genre对应的预算均值
    for j in genre_list:
        budget_s.loc[j]=budget_df.loc[:,[j,'budget']].groupby(j, as_index=False).mean().loc[1,'budget']
    budget_s
    
    # 再接着,横向合并 profit_s 和 budget_s
    profit_budget = pd.concat([profit_s, budget_s], axis=1)
    profit_budget.columns = ['profit', 'budget']
    
    #添加利润率列
    profit_budget['rate'] = (profit_budget['profit']/profit_budget['budget'])*100
    
    # 降序排序
    profit_budget_sort=profit_budget.sort_values(by='budget',ascending = False)
    profit_budget_sort.head(2)
    
    # 绘制不同类型电影平均预算和利润率(组合图)
    x = profit_budget_sort.index
    y1 = profit_budget_sort.budget
    y2 = profit_budget_sort.rate
    
    # 返回profit_budget的行数
    length = profit_budget_sort.shape[0]
    fig = plt.figure(figsize=(12,9))
    
    # 左轴
    ax1 = fig.add_subplot(1,1,1)
    plt.bar(range(0,length),y1,color='b',label='平均预算')
    plt.xticks(range(0,length),x,rotation=90, fontsize=12)  # 更改横坐标轴名称
    ax1.set_xlabel('年份')                   # 设置x轴label ,y轴label
    ax1.set_ylabel('平均预算',fontsize=16)
    ax1.legend(loc=2,fontsize=12)
    
    #右轴
    # 共享x轴,生成次坐标轴
    ax2 = ax1.twinx()
    ax2.plot(range(0,length),y2,'ro-.') 
    ax2.set_ylabel('平均利润率',fontsize=16)
    ax2.legend(loc=1,fontsize=12)
    
    # 将利润率坐标轴以百分比格式显示
    import matplotlib.ticker as mtick
    fmt='%.1f%%'
    yticks = mtick.FormatStrFormatter(fmt)
    ax2.yaxis.set_major_formatter(yticks)
    
    # 设置图片title
    ax1.set_title('不同类型电影平均预算和利润率',fontsize=20)
    ax1.grid(False)
    ax2.grid(False)
    plt.savefig("不同电影平均预算+利润率.png",dpi=300)
    
    plt.show()
    
    # 绘制不同类型电影预算和利润(条形图)
    profit_budget_sort.iloc[:,0:2].plot(kind='bar', figsize=(12,9),color = ['blue', 'r'])
    plt.title('Budget and Profit',fontsize = 20)
    plt.xlabel('len',fontsize = 16)
    plt.grid(False)
    plt.savefig('不同类型电影预算和利润-条形图.png',dpi=300)
    

    电影关键词

    # 引入包
    from wordcloud import WordCloud
    
    #keywords关键词分析
    keywords_list = []
    for i in df['keywords']:
        keywords_list.append(i)
    
    # 将所有nan转换成空字符串
    df = df.where(df.notnull(), '')
    
    keywords = ",".join(keywords_list)
    
    wordcloud = WordCloud(
                    background_color = 'black',
                    stopwords = [],
                    random_state=9, # 设置一个随机种子,用于随机着色
                    max_words = 3000,
                    width = 2400,
                    height = 1200,
                    scale=1).generate(keywords)
    
    plt.figure(figsize = (23, 8), dpi = 80)
    plt.imshow(wordcloud)
    plt.axis("off")
    plt.show()
    

    when

    查看runtime的类型,发现是object类型,也就是字符串,所以,先进行数据转化。

    # 转换数据类型
    df.runtime = df.runtime.convert_objects(convert_numeric=True)
    df.runtime.describe()
    

    电影时长(绘制电影时长直方图)

    
    # 设置matplotlib正常显示中文和负号
    plt.rcParams['font.sans-serif'] = ['SimHei']   # 用黑体显示中文
    plt.rcParams['axes.unicode_minus'] = False     # 正常显示负号
    
    plt.figure(figsize= (23, 10), dpi = 80)
    plt.hist(df.runtime, bins = 40, facecolor="blue", edgecolor="black", alpha=0.7)
    
    # 显示横轴标签
    plt.xlabel("电影市场")
    # 显示纵轴标签
    plt.ylabel("频数/频率")
    # 显示图标题
    plt.title("频数/频率分布直方图", fontsize = 20)
    plt.show()
    

    发行时间(绘制每月电影数量和单片平均票房)

    x = list(range(1, 13))
    # 影片数量
    film_num = df.groupby('release_month').size()
    # 每月单片平均票房
    revenue_mean = df.groupby('release_month').revenue.mean()
    
    plt.figure(figsize = (23, 12), dpi = 200)
    fig,ax1 = plt.subplots()
    ax2 = ax1.twinx()           # 做镜像处理
    ax1.bar(x, film_num)
    ax2.plot(x, revenue_mean, color = 'r')
    
    ax1.set_xlabel('月份', fontsize = 12)    #设置x轴标题
    ax1.set_ylabel('每月电影数量',color = 'g', fontsize = 12)   #设置Y1轴标题
    ax2.set_ylabel('单片平均利润',color = 'b', fontsize = 12)   #设置Y2轴标题
    

    where

    本数据集收集的是美国地区的电影数据,对于电影的制作公司以及制作国家,在本次的故事背景下不作分析。

    who

    分析票房分布及票房Top10的导演

    revenue = df['revenue']
    
    plt.figure(figsize = (26, 15), dpi = 200)
    # 刻度字体大小13
    plt.tick_params(labelsize = 20)
    plt.subplot(221)
    plt.hist(revenue, bins = 100, color = 'blue', facecolor="blue", edgecolor="black", alpha=0.7)
    plt.title("票房分布", fontsize = 20)
    plt.subplot(222)
    director_df = df[['crew', 'revenue', 'vote_average']]
    director_df = director_df.groupby('crew').mean()
    director_revenue_top10 = director_df.sort_values(ascending = True, by = 'revenue').tail(10)
    
    bar_x = director_revenue_top10.index
    bar_y = director_revenue_top10.revenue
    
    plt.bar(bar_x, bar_y, color = 'blue')
    plt.xticks(rotation = 30)
    plt.title("票房Top10导演", fontsize = 20)
    
    plt.show()
    

    分析评分分布及评分Top10导演

    vote = df['vote_average']
    
    plt.figure(figsize = (26, 15), dpi = 200)
    
    # 刻度字体大小13
    plt.tick_params(labelsize = 20)
    
    plt.subplot(221)
    plt.hist(vote, bins = 200, color = '#3c5e91', facecolor="#3c5e91", edgecolor="black", alpha=0.7)
    plt.title("评分分布", fontsize = 20)
    
    plt.subplot(222)
    
    director_vote_top10 = director_df.sort_values(ascending = True, by = 'vote_average').tail(10)
    
    bar_x = director_vote_top10.index
    bar_y = director_vote_top10.vote_average
    
    plt.bar(bar_x, bar_y, color = '#3c5e91')
    plt.xticks(rotation = 30)
    plt.title("评分Top10导演", fontsize = 20)
    
    plt.savefig("分析评分分布及评分Top10导演", dpi = 300)
    
    plt.show()
    

    how

    原创VS改编(饼图)

    # 改编
    based = pd.DataFrame()
    based['title'] = df[df['keywords'].str.contains('based on')].title
    based['budget'] = df[df['keywords'].str.contains('based on')].budget
    based['revenue'] = df[df['keywords'].str.contains('based on')].revenue
    
    # 原创
    original = pd.DataFrame()
    original['title'] = df[df['keywords'].str.contains('based on') == False].title
    original['budget'] = df[df['keywords'].str.contains('based on') == False].budget
    original['revenue'] = df[df['keywords'].str.contains('based on') == False].revenue
    
    # 可视化
    
    # 数据总数量
    total_num = len(df)
    
    # 改编数量
    based_num = len(based)
    
    # 原创数量
    original_num = len(original)
    
    plt.figure(figsize=(15,7), dpi = 75)
    labels= ['改编', '原创']
    sizes = [based_num/total_num, original_num/total_num]
    explode = (0.1, 0)
    plt.pie(sizes,explode=explode,labels=labels,autopct='%1.1f%%',shadow=False,startangle=150)
    plt.title("原创VS改编占比", fontsize = 20)
    plt.show()  
    

    原创VS改编预算/利润率(组合图)

    bar_x = [1, 2]
    width = 0.1
    labels = ["改编", "原创"]
    
    # 预算
    bar_y1 = [based['budget'].sum(), original['budget'].sum()]
    # 利润
    bar_y2 = [based['revenue'].sum(), original['revenue'].sum()]
    plot_y = [(based['revenue'].sum() - based['budget'].sum())/based['budget'].sum(), (original['revenue'].sum() - original['budget'].sum())/original['budget'].sum()]
    
    plt.figure(figsize= (132, 125), dpi = 200)
    
    fig,ax1 = plt.subplots()
    ax2 = ax1.twinx() 
    
    ax1.bar([i-width/2 for i in bar_x], bar_y1, width = width, label = "预算")
    ax1.bar([i+width/2 for i in bar_x], bar_y2, width = width, label = "票房")
    ax1.set_xticks(bar_x)
    ax1.set_xticklabels(labels)
    ax1.legend()
    
    ax2.plot(bar_x, plot_y, color='red', linestyle='--', marker = 'o')
    ax2.legend("平均利润率")
    
    plt.show()
    

    how much

    计算相关系数(票房相关系数矩阵)

    import seaborn as sns
    
    revenue_corr = df[['runtime','popularity','vote_average','vote_count','budget','revenue']].corr()
    
    plt.figure(figsize = (25, 12), dpi = 20)
    plt.rcParams['figure.figsize']=(120,120)
    sns.heatmap(
                revenue_corr,
                annot=True, # 在每个单元格内显示标注
                cmap="Blues", # 设置填充颜色:黄色,绿色,蓝色
                cbar=True,  # 显示color bar
                linewidths=0.5, # 在单元格之间加入小间隔,方便数据阅读
               )
    
    plt.savefig('票房相关系数矩阵.png',dpi=300)
    

    票房影响因素散点图

    # 绘制散点图
    fig = plt.figure(figsize=(17,5))
    
    # 预算影响
    budget_revenue = df[['budget', 'revenue']]
    
    ax1 = plt.subplot(1,3,1)
    ax1 = sns.regplot(x='budget', y='revenue', data=budget_revenue, x_jitter=.1,color='r',marker='x')
    ax1.text(1.6e8,2.2e9,'r=0.7',fontsize=16)
    plt.title('预算影响',fontsize=20)
    plt.xlabel('预算',fontsize=16)
    plt.ylabel('收入',fontsize=16)
     
    # 受欢迎度影响
    popularity_revenue = df[['popularity', 'revenue']]
    ax2 = plt.subplot(1,3,2)
    ax2 = sns.regplot(x='popularity', y='revenue', data=popularity_revenue, x_jitter=.1,color='g',marker='o')
    ax2.text(500,3e9,'r=0.59',fontsize=16)
    plt.title('受欢迎程度影响',fontsize=18)
    plt.xlabel('欢迎程度',fontsize=16)
    plt.ylabel('收入',fontsize=16)
    
    # 投票数
    vote_revenue = df[['vote_count', 'revenue']]
    ax3 = plt.subplot(1,3,3)
    ax3 = sns.regplot(x = 'vote_count', y = 'revenue', data = vote_revenue, x_jitter = .1,color='b',marker='v')
    ax3.text(7000,2e9,'r=0.75',fontsize=16)
    plt.title('投票数量影响',fontsize=20)
    plt.xlabel('投票数量',fontsize=16)
    plt.ylabel('收入',fontsize=16)
    
    plt.show()
    

  • 相关阅读:
    [UWP]如何使用Fluent Design System (下)
    [UWP]如何使用Fluent Design System (上)
    [UWP]了解IValueConverter
    [UWP]了解TypeConverter
    [UWP]本地化入门
    [WPF]本地化入门
    [UWP]创建一个进度按钮
    [UWP]分享一个基于HSV色轮的调色板应用
    [UWP]使用Writeable​Bitmap创建HSV色轮
    [UWP]理解及扩展Expander
  • 原文地址:https://www.cnblogs.com/Gazikel/p/15685294.html
Copyright © 2011-2022 走看看