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()
    

  • 相关阅读:
    Best Time to Buy and Sell Stock
    Remove Nth Node From End of List
    Unique Paths
    Swap Nodes in Pairs
    Convert Sorted Array to Binary Search Tree
    Populating Next Right Pointers in Each Node
    Maximum Subarray
    Climbing Stairs
    Unique Binary Search Trees
    Remove Duplicates from Sorted Array
  • 原文地址:https://www.cnblogs.com/Gazikel/p/15685294.html
Copyright © 2011-2022 走看看