美文网首页
项目05_国产烂片深度揭秘

项目05_国产烂片深度揭秘

作者: 我是屁江 | 来源:发表于2019-06-17 11:43 被阅读0次

    -- coding: utf-8 --

    """
    Created on Tue Oct 16 16:40:16 2018

    项目 11 国产烂片深度揭秘

    @author: peng.jiang1
    """
    """
    Note:
    1 在绘制hist 直方图时分组的依据?bins=? 经验?
    2 在绘制 box 箱型图时 箱型图的向 水平还是立着? 参数vert=True 默认垂直
    3 .str.contains('obj') 可以计算字符串中是否包含指定的字符, 如果需要选择不包含
    某些字符时 可以结合bool做选择(推荐bool 选择)
    4 DataFrame 字段中的字符串中有空格 可以使用替换为空 replace()
    5 在DataFrame中操作值 一定先转str再使用方法
    6 当DF的值为列表时 如何计算此列表的长度 直接調用.str.len()的方法
    7 用来存储数据的变量不要一起赋值, 因为指向问题 内存地址一致,会覆盖
    8 需要存储数据可以直接存在series 和Df中 即重新索引赋值
    9 在绘制子图时 通过add_subplot()新增 无需变量名

    """

    导入模块

    import os
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    from bokeh.plotting import show, output_file, figure
    from bokeh.models import ColumnDataSource, HoverTool
    import warnings

    warnings.filterwarnings('ignore')

    自定函数

    def get_info(path):
    '''
    统计数据的基本信息:
    1 数据量
    2 数据的columns
    3 数据中的缺失值数量
    返回:读取后的DataFrame
    '''
    data = pd.read_excel(path, sheet_name=0, header=0)
    print('数据量:%d'%len(data))
    print('数据字段:', data.columns.tolist())
    print('缺失值量:%d'%len(data[data.isnull().values == True]))

    return data
    

    def graph_comment(data):
    '''
    绘制豆瓣评分的分布 -- 直方图 箱型图
    '''
    fig = plt.figure(figsize=(10, 8))
    fig.add_subplot(211)
    data['豆瓣评分'].dropna().plot(kind='hist', bins=25, color='green',
    alpha=0.6, edgecolor='gray')
    plt.grid(linestyle='--', color='gray', axis='y', alpha=0.5)
    plt.title('豆瓣评分-直方图')
    plt.tight_layout()

    fig.add_subplot(212)
    data['豆瓣评分'].dropna().plot(kind='box', vert=False)
    plt.grid(linestyle='--', color='gray', axis='x', alpha=0.5)
    plt.title('豆瓣评分-箱型图')
    plt.tight_layout()
    
    plt.savefig('豆瓣评分分布情况.jpg', dpi=500)
    

    def data_type(data_lp, data):
    '''
    统计电影的类型
    '''
    # 得到烂片的类型数据
    data_lp = data_lp['类型'].dropna().str.replace(' ', '').tolist()
    lst_type = []
    for i in data_lp:
    lst_type.extend(i.split('/'))
    s = pd.Series(lst_type, name='lp').value_counts()
    lp_type = pd.DataFrame(s)

    # 得到总片的类型数据
    data = data[data['豆瓣评分'].isnull() == False]
    data = data['类型'].dropna().str.replace(' ', '').tolist()
    data_type = []
    for i in data:
        data_type.extend(i.split('/'))
    s = pd.Series(data_type, name='sum').value_counts()
    d_type = pd.DataFrame(s)
    
    # 合并数据
    result = pd.merge(d_type, lp_type, left_index=True, right_index=True,
                      how='right')
    result['lp_per'] = result['lp'] / result['sum']
    result.sort_values(by='lp_per', ascending=False, inplace=True)
    
    return result
    

    def circle_graph(data, title):
    '''
    使用bokeh绘制散点
    '''
    output_file(title + '.html') # 创建html文件

    source = ColumnDataSource(data)  # 构建bokeh数据
    # 创建显示标签
    hover = HoverTool(tooltips=[('数据量', '@lp'),
                                ('烂片比例', '@lp_per')])
    
    # 创建工具栏
    tools = '''
          box_select, reset, wheel_zoom, pan
    '''
    index = data.index.tolist()
    fig = figure(x_range=index, plot_width=300, plot_height=300,
                 toolbar_location='above', tools=[hover, tools])  # 设置绘图空间
    fig.circle(data.index, data['lp'],
               line_color='black', line_alpha=0.7,
               fill_color='red', fill_alpha=0.7,
               size=data['lp_per'], source=source)
    show(fig)
    

    def data_state(data):
    '''
    计算中国和哪些国家合拍出烂片
    '''
    # 数据清洗
    data = data[['制片国家/地区', '豆瓣评分']]
    data.dropna(inplace=True)
    data = data[data['制片国家/地区'].str.contains('中国大陆')] # 剔除不包含中国
    # 删除"中国大陆 "“中国”、“台湾”、“香港”等噪音数据
    data = data[data['制片国家/地区'].str.contains('台湾') == False]
    data = data[data['制片国家/地区'].str.contains('香港') == False]
    data = data[data['制片国家/地区'].str.contains('/') == True]
    state_lp = data[data['豆瓣评分'] < score] # 筛选烂片国家

    return data, state_lp
    

    def state_count(state, state_lp):
    '''
    统计合作国家烂片率
    '''
    state_lp = state_lp['制片国家/地区'].str.replace(' ', '').tolist()
    lst_state = []
    for i in state_lp:
    lst_state.extend(i.split('/'))
    s = pd.Series(lst_state, name='lp').value_counts()
    lp_type = pd.DataFrame(s)

    # 得到总片的国家数据
    state = state['制片国家/地区'].str.replace(' ', '').tolist()
    data_state = []
    for i in state:
        data_state.extend(i.split('/'))
    s = pd.Series(data_state, name='sum').value_counts()
    d_type = pd.DataFrame(s)
    
    result = pd.merge(d_type, lp_type, left_index=True, right_index=True,
                      how='left')
    result['lp_per'] = result['lp'] / result['sum']
    result.sort_values(by='lp_per', ascending=False, inplace=True)
    
    return result
    

    def player(data):
    '''
    统计影片的主演人数
    '''
    # 数据清洗
    data = data[['电影名称', '主演', '豆瓣评分']]
    data = data[data['电影名称'].duplicated() == False]
    data = data[data['电影名称'].notnull() == True]
    data = data[data['豆瓣评分'].notnull() == True]
    data = data[data['主演'].notnull() == True]

    # 计算总的数据
    data['主演'] = data['主演'].str.replace(' ','').str.split('/')
    data['num'] = data['主演'].str.len()
    # 分組
    bins = [0, 2, 4, 6, 9, 100]
    data['cut'] = pd.cut(data['num'], bins)
    result1 = data.groupby(by='cut')['电影名称'].count()
    result1 = pd.DataFrame(result1)
    
    # 计算烂片的数量
    data_lp = data[data['豆瓣评分'] < score]
    result2 = data_lp.groupby(by='cut')['电影名称'].count()
    result2 = pd.DataFrame(result2)
    
    result = pd.merge(result1, result2, how='left', left_index=True,
                      right_index=True)
    result.columns =['影片总数', '烂片总数']
    result['per'] = result['烂片总数'] / result['影片总数']
    result['主演人数分类'] = ['1-2人', '3-4人', '5-6人', '7-9人', '10人以上']
    result.set_index('主演人数分类', inplace=True)
    
    return result
    

    def star_lp_per(data, name):
    '''
    按名字查询烂片率
    '''
    # 数据清洗
    data = data[['电影名称', '主演', '豆瓣评分']]
    data = data[data['电影名称'].duplicated() == False]
    data = data[data['电影名称'].notnull() == True]
    data = data[data['豆瓣评分'].notnull() == True]

    # 筛选数据
    data1 = data[data['主演'].str.contains(name) == True]   # 主演的电影
    data2 = data1[data1['豆瓣评分'] < score]
    
    print('%s的烂片率:%.2f'%(name, len(data2)/len(data1)))
    print('烂片如下:')
    print(data2)
    

    def film_count(data):
    '''
    统计每年不同导演的产量
    '''
    # 数据清洗
    data = data[['电影名称', '导演', '豆瓣评分', '上映日期']]
    data = data[data['电影名称'].duplicated() == False]
    data = data[data['电影名称'].notnull() == True]
    data = data[data['豆瓣评分'].notnull() == True]
    data = data[data['上映日期'].notnull() == True]
    data = data[data['导演'].notnull() == True]
    data['year'] = data['上映日期'].str.replace(' ', '').str[:4]

    # 统计导演
    lst = []
    for i in data['导演'].str.replace(' ', '').tolist():
        lst.extend(i.split('/'))
    lst = list(set(lst))
    
    # 按导演统计
    s1 = pd.Series(name='count')
    s2 = pd.Series(name='count')
    for name in lst:
        datai = data[data['导演'].str.contains(name) == True]
        dataj = datai[datai['豆瓣评分'] < score]
        s1[name] = len(datai)
        s2[name] = len(dataj)  
        
    df1 = pd.DataFrame(s1)
    df2 = pd.DataFrame(s2)
    df = pd.merge(df1, df2, left_index=True, right_index=True, how='left')
    df = df[df['count_x'] >= 10]
    df['per'] = df['count_y']/df['count_x']
    
    # 按年份和导演统计影片产量
    data_year = pd.DataFrame(columns=['电影名称', '导演', '豆瓣评分', '上映日期'])
    #  统计烂片导演
    lst_lp = df[df['count_y'] !=0 ].index.tolist()
    for name in lst_lp:
        data_name = data[data['导演'].str.contains(name) == True]
        data_name['导演'] = name
        data_year = pd.concat([data_year, data_name])
        
    result = data_year.groupby(by=['year', '导演'])['豆瓣评分'].agg({
            'count':'count',
            'mean':np.mean
                })
    result.reset_index(inplace=True)
    
    return df, result
    

    def bokeh_circle(data, title):
    '''
    使用bokeh绘制散点
    '''
    output_file(title + '.html') # 创建html文件
    data.rename(columns={'导演':'dy'}, inplace=True)
    data['color'] = 'gray'
    data['color'][data['dy'] == '王晶'] = 'blue'
    data['color'][data['dy'] == '周伟'] = 'yellow'
    data['color'][data['dy'] == '徐克'] = 'red'
    source = ColumnDataSource(data) # 构建bokeh数据
    # 创建显示标签
    hover = HoverTool(tooltips=[('电影评分均值', '@mean'),
    ('该年电影产量', '@count')])

    # 创建工具栏
    tools = '''
          box_select, reset, wheel_zoom, pan
    '''
    fig = figure(plot_width=300, plot_height=300,
                 toolbar_location='above', tools=[hover, tools])  # 设置绘图空间
    data1 = data[data['dy'] == '王晶']
    fig.circle(data1['year'], data1['mean'],
               line_color=data1['color'], line_alpha=0.7,
               fill_color=data1['color'], fill_alpha=0.7,
               size=data1['count'])
    data1 = data[data['dy'] == '周伟']
    fig.circle(data1['year'], data1['mean'],
               line_color=data1['color'], line_alpha=0.7,
               fill_color=data1['color'], fill_alpha=0.7,
               size=data1['count'])
    data1 = data[data['dy'] == '徐克']
    fig.circle(data1['year'], data1['mean'],
               line_color=data1['color'], line_alpha=0.7,
               fill_color=data1['color'], fill_alpha=0.7,
               size=data1['count'])
    data1 = data[data['dy'] == '邓衍成']
    fig.circle(data1['year'], data1['mean'],
               line_color=data1['color'], line_alpha=0.7,
               fill_color=data1['color'], fill_alpha=0.7,
               size=data1['count']) 
    show(fig)   
    

    if name == 'main':

    path = r'C:\Users\pj2063150\Desktop\项目\项目11国产烂片深度揭秘'
    os.chdir(path)
    
    # 1 以“豆瓣评分”为标准,看看电影评分分布,及烂片情况
    data = get_info('moviedata.xlsx')  # 查看并获取数据
    #graph_comment(data)
    
    score = data['豆瓣评分'].dropna().describe()['25%']   # 烂片标准评分
    data_lp = data[data['豆瓣评分'] < score].sort_values(by='豆瓣评分')  # 筛选烂片
    
    # 2 分析什么题材电影烂片最多
    # 创建数据
    lst_type = data_type(data_lp, data)
    lst_type['size'] = (lst_type['lp']**0.5)*2
    #circle_graph(lst_type, '烂片题材情况-散点图')   # 绘制图表
    
    # 3 与什么国家合拍更可能产生烂片
    state = data_state(data)[0]
    state_lp = data_state(data)[1]
    state_count(state, state_lp)  # 计算合作国家的烂片率
     
    # 4 卡司数量是否和烂片有关(主演人数)
    player_num = player(data)
    # 按明星查询烂片率
    star_lp_per(data, '吴亦凡')
    
    # 5 不同导演每年电影产量情况如何
    data5 = film_count(data)
    data5_dir = data5[0]
    data5_year = data5[1]
    # 绘制图表
    bokeh_circle(data5_year, '不同导演每年电影产量及评分均值')
          
    print('Finished!')
    
    豆瓣评分分布情况.jpg

    相关文章

      网友评论

          本文标题:项目05_国产烂片深度揭秘

          本文链接:https://www.haomeiwen.com/subject/inebfctx.html