267019条猫眼数据加持,原来你是这样的《流浪地球》——python数据分析全流程代码实现!

2019年春节档,《流浪地球》横空出世,在强势口碑加持下,上映两周多票房即突破40亿! 与之相随的主题也霸占了春节期间的话题榜。 作为一部现象级的电影,笔者也很感兴趣,特意爬取了2月5日(初一)至2月12日(初八) 267019条猫眼影评,多角度可视化分析了《流浪地球》的数据规律。 接下来,跟我看看这267019人究竟说了什么吧!

数据分析准备工作

  • 整个数据分析分为数据爬取、数据清洗、数据可视化和文本分析四个板块
  • 项目采用Anaconda环境,过程仍需安装多个第三方模块

所需第三方模块(需提前安装)

  • 数据可视化:pyecharts(是一个用于生成 Echarts 图表的类库).
  • 文本分析:jieba(中文分词),wordcloud(生成词云)等

(一)数据爬取阶段

1、工具库准备(备用模块:time,random,datetime,requests,json)

2、备用user-agents(准备多个可用的user_agents,应用于爬虫阶段)

3、爬虫封装代码(详细的爬虫实现代码)

源代码github地址:https://github.com/Willsgao/Personal-projects/
爬虫阶段总结
  • 1、爬取2019-02-05日——2019-02-12日,8天共267019条评价数据。
  • 2、实际爬取过程中会因为网站的反扒机制多次中断,导致部分数据丢失。

(二)数据清洗阶段

  • 1、此阶段主要依靠pandas对原始数据进行预处理
  • 2、爬虫阶段得到的数据分布在多个csv文件中需要进行合并
  • 3、数据中存在空值,根据需求进行删除或补充操作
1、导入数据清洗所需工具库
import pandas as pd
import glob  # 在csv文件合并中读取所有的csv文件
2、将爬取的多个csv文件进行合并
# 读取爬取的所有csv文件
csv_files = glob.glob('./*.csv')

# 将csv文件进行合并
for file in csv_files:
    data = pd.read_csv(file, names=['昵称','城市','评语','评分','日期','性别标签'],
                       encoding='utf_8_sig',engine='python',header=None)
    data.to_csv('合并文件/流浪地球01_comments.csv', mode='a', 
                encoding='utf_8_sig', index=False, sep=',')
3、数据基本信息特征
# 读取合并后的文件信息
datas = pd.read_csv('合并文件/流浪地球01_comments.csv',
                encoding='utf_8_sig',engine='python')
# 查看数据的基本信息属性
datas.describe()

在这里插入图片描述

4、所需的目标数据的预处理
# 统计各城市出现的数据信息
ct_datas = pd.DataFrame(datas['城市'])
# 将城市名称为空的数据删除
ct_datas = ct_datas.dropna(axis=0)
print(ct_datas.size)

# pandas读取会员的评分数据
df_score =  pd.DataFrame(datas['评分'])
# 将评分为空的数据删除
df_score = df_score.dropna(axis=0)
print(df_score.size)

# 读取会员的评语数据
dt_coms = pd.DataFrame(datas['评语'])
# 将评语为空的数据删除
dt_coms = dt_coms.dropna(axis=0)
print(dt_coms.size)
# 将评语保存为txt文档
dt_coms.to_csv("流浪地球_影评.txt",
               sep='\t', index=False)
5、数据清洗小结
  • 主要根据数据分析的业务需求进行初步的数据处理
  • 更加细致的数据处理在业务分析阶段实现

(三)数据分布可视化

  • 利用pyecharts可视化参与影评的粉丝分布情况
  • 分别通过Geo和Bar函数进行数据可视化
1、指明文件编码格式,识别中文字符
# 导入相关工具库
import importlib
import sys
importlib.reload(sys)
2、城市分布信息处理
  • 为实现Geo可视化全国粉丝分布,对ct_datas进行处理
  • 定义数据格式处理的相关函数
    ******* 详细代码见github源代码******
# 城市信息列表化
# 将读取的城市特征信息转化为列表
def list_cities(ct_datas):
    pass
    return city_lists

# 城市列表字典化,将城市列表转化为键为城市值为人数的字典
def set_list_cities(city_lists):
    pass
    return city_sets

# Geo格式化,将城市字典转化为Geo所需的数据格式
# 将城市信息和评论数量以元组格式添加到列表中
def geo_city_infos(city_sets):
    pass
    return city_infos

# 将Geo格式化的列表重新转化为字典格式
def set_info_cities(city_infos):
    pass
    return city_sets
# 生成城市数据字典
city_sets = set_list_cities(city_lists)
print(len(city_sets))

# 生成格式化城市数据
city_infos = geo_city_infos(city_sets)
print(len(city_infos))
data = city_infos
3、Geo可视化粉丝分布图
  • pyecharts源代码的数据库中无法识别所有的城市,因此不能识别的城市需要特殊处理。
  • 方法一是将所有不能识别的城市数据删除;
  • 方法二是在源代码城市数据库中添加新城市的经纬度值。
考虑到操作的简便性,此处采用方法一,将不能识别的城市数据删除
# Geo绘图函数
def geo_picture(data, city_sets):
    # 导入相关工具库
    # 导入Geo模块进行城市数据分析
    from pyecharts import Geo
    
    useless_cities = []
    city_infos = []
    for i in range(len(data)):
        geo = Geo("《流浪地球》全国观影粉丝分布图", "data from Maoyan", 
                  title_color="#fff",title_pos="center", width=1000,
                  height=750, background_color='#404a59')
        attr, value = geo.cast(data)

        try:
            geo.add("", attr, value, visual_range=[0, 200], maptype='china',type="effectScatter",
                    visual_text_color="#fff",symbol_size=10, is_visualmap=True)
        except Exception as e:
    #         print(e)
            # 在异常信息中提取无法被pyecharts识别的城市
            city = str(e).split()[-1]
            # 将不能识别的城市名称收集到列表中
            useless_cities.append(city)
            # 剔除无法识别的城市信息
            city_sets.pop(city)
            city_infos = geo_city_infos(city_sets)
            data = city_infos
    #生成html文件
    geo.render("全国观影粉丝分布图.html")
    return geo,city_infos,useless_cities


# 处理不能识别的城市名称,重新参与画图
def handle_cities(filename, city_sets):
    # 读取未识别的城市名称
    ul_cities = []
    with open(filename,'r',encoding='utf_8') as f:
        ul_lists = f.readlines()
        
    # 删除非中文格式的城市
    for city in ul_lists:
        ch = city.strip()[0]
        if u'\u4e00' <= ch <= u'\u9ffff':
            ul_cities.append(city.strip())
    print(len(ul_cities))
    
    # 判断是否由于下面集合中的字的缺失或是多余导致
    ad_re_cities = []
    cityname = ''
    lists = ['县','区','市','州']
    for city in ul_cities:
        if city[-1] not in lists:
            for j in lists:
                cityname = city+j
                ad_re_cities.append((cityname,city_sets[city]))
        elif len(city)>=3:
            cityname = ''.join(city[:-1])
            ad_re_cities.append((cityname, city_sets[city]))
        else:
            continue
    return ad_re_cities


# 存储不能识别的城市信息
def store_cities(useless_cities,filename):
    ul_cities = pd.DataFrame(useless_cities)
    ul_cities.to_csv(filename,sep='\t', index=False)
# 运行Geo模块
pre_city_sets = set_list_cities(city_lists)
print(len(pre_city_sets))
geo,city_infos,useless_cities = geo_picture(data, pre_city_sets)

# 定义存储不能识别城市的文件名称
filename = '未识别城市.txt'

# 存储城市信息
store_cities(useless_cities,filename)
# 生成处理后的新城市信息
print(len(city_sets))
ad_re_cities = handle_cities(filename, city_sets)

​​# 处理后的城市与已识别的城市信息合并
final_city_infos = ad_re_cities + city_infos
cur_city_sets = set_info_cities(final_city_infos)
# print(next_city_sets)

# 重新运行Geo模块
geo,_,_ = geo_picture(final_city_infos,cur_city_sets)

# 绘制全国观影粉丝分布图
# 直接在notebook中显示
geo

在这里插入图片描述

Geo可视化粉丝分布小结
  • pyecharts识别城市能力有限,导致380个左右的城市信息无法识别
  • 总体上来说主要城市信息是能正常识别的,因此不会对头部信息有较大影响
  • 对于定型化了解全国影迷分布仍具有很大的参考价值
具体分布信息见上图
  • 1、中东部是《流浪地球》影迷和影评的主力;
  • 2、广大的西部地区影评人数严重不足;
  • 3、影评的密度与地区人口的分布密度正相关。
4、利用Bar可视化评论头部城市信息
  • 利用pyecharts中的Bar模块进行分析
  • 查看影评数量在前20名的城市信息
  • 利用pyecharts中的Style模块定义可视化图形
from pyecharts import Bar
from pyecharts import Style

# 定义样式
style = Style(
    title_color='#fff',
    title_pos='center',
    width=800,
    height=500,
    background_color='#404a59',
    subtitle_color='#fff'
)

# 根据城市数据生成柱状图
city_counts = ct_datas.groupby("城市").size()
city_sorted = city_counts.sort_values(ascending=False).head(20)

bar = Bar("《流浪地球》评星人来源排行TOP20", "蜗牛行天下", **style.init_style)
attr, value = bar.cast(list(city_sorted.items()))
bar.add("", attr, value, is_visualmap=True, visual_range=[0, 2500],
        visual_text_color='#fff', label_color='#fff',
        xaxis_label_textcolor='#fff', yaxis_label_textcolor='#fff', 
        is_more_utils=True,is_label_show=True)

# 保存可视化图片文件
bar.render("评星人来源排行-柱状图.html")
# 图像可视化
bar

在这里插入图片描述

Bar可视化分析小结
  • 从上图可见,城市粉丝评论数量顺序与城市的经济实力排名相吻合。
  • 此外,城市粉丝评论数量顺序也与城市人口数量排名正相关。
  • 由此可以初步推断,城市经济实力越强。人口越多,市民的观影数量越多,娱乐生活越丰富。
5、Pie模块可视化《流浪地球》的星级评价&区分性别
  • 利用pyecharts的Pie模块分析《流浪地球》的评分分布
  • 将评分进行分段处理,用一星到五星来标定影片评价等级
  • 分别考察不同性别影迷对《流浪地球》的评分结果,探究性别影响。
  • 性别缺失值较多,但因为数据是否缺失没有明显的性别差异,缺失值可以删除
# 构建Pie图生成函数
def genPiePicture(df_score):
    pass   # 详细代码见文末github地址
    return pie
分性别处理影评数据
# 处理性别数据
# 1、删除缺失值
gender_datas = datas.dropna(subset=['性别标签'])
print(len(gender_datas))

# 2、分别读取男女性别数据,男gender值为'1.0',女为'2.0'
male_datas = gender_datas[gender_datas.性别标签=='1.0']
female_datas = gender_datas[gender_datas.性别标签=='2.0']

# 3、分别读取男女会员的评分数据
male_score =  pd.DataFrame(male_datas['评分'])
female_score =  pd.DataFrame(female_datas['评分'])
# 生成男性的评分pie图
male_pie = genPiePicture(male_score)
male_pie
# 生成女性的评分pie图
female_pie = genPiePicture(female_score)
female_pie
男性星级评价比例图

在这里插入图片描述

女性星级评价比例图

在这里插入图片描述

《流浪地球》星级评价小结
  • 男女影评者均有85%左右的比例对《流浪地球》给出了5星的评价。
  • 男女影评者具有超过93%的影评者对《流浪地球》给出了超过4星的评价。
  • 《流浪地球》是一部基本没有性别区分度的影片,男女通吃。
  • 《流浪地球》是一部评价很高(评分数据超过大多数影片),值得一看。

(四)评语文本分析

  • 利用jieba分词工具包对评语进行分词处理,分析评语文本信息。
  • 对所得的评语分词进行头部分析,利用wordcloud生成词云,可视化评语。
  • 原始评语过于庞大(700万字),此处不做详细分析。
  • 更为详细的文本分析见‘《流浪地球》猫眼评语文本分析’一文。
1、导入文本分析工具包
import jieba
import matplotlib.pyplot as mp
from wordcloud import STOPWORDS, WordCloud
from os import path
from PIL import Image
import numpy as np
2、获取样本评语数据
  • 为简化分析,随机选择了一个小样本(1.6万字左右)进行简要分析。
# 获取所有的评论
comments = []

with open("流浪地球_影评01.txt", 'r', encoding='utf-8') as f:
    rows = f.readlines()
    for row in rows:
        try:
            comment = row.strip().split(',')
        except IndexError:
            continue
        if comment:
            comments.append(comment)
print(len(comments))
# 设置分词
com_aft_spl = jieba.cut(
    str(comments),cut_all=False) # 非全模式分词,cut_all=False
words = ' '.join(com_aft_spl)
print(len(words))

# 设置停用词,在默认停用词基础上添加新的停用词
stopwords = STOPWORDS.copy()
wd_libs = ['电影','一部','一个','没有','什么','有点','这部','这个','不是','我们',
          '真的','感觉','觉得','还是','但是','就是','流浪地球','流浪','地球','中国']
for wl in wd_libs:
    stopwords.add(wl)
print(len(stopwords))
温馨提示:此处有坑font_path设置不好,中文词云可能会乱码!
# 词云代码构建
d = path.dirname('__file__')
nana_coloring = np.array(Image.open(path.join(d, "car.png"))) # 词云形状由图片‘car.png’决定
my_wordcloud = WordCloud( background_color = 'white',      # 设置背景颜色
                            mask = nana_coloring,          # 设置背景图片
                            max_words = 200,              # 设置最大现实的字数
                            stopwords = stopwords,         # 设置停用词
                            font_path = 'simhei.ttf',
                            max_font_size = 100,            # 设置字体最大值
                            random_state = 30             # 设置有多少种随机生成状态,即有多少种配色方案
                          )
my_wordcloud.generate(words)
分词词云背景图片,决定词云形状。

在这里插入图片描述

# 可视化词云图
mp.imshow(my_wordcloud,cmap=mp.cm.gray, interpolation='bilinear')    # 显示词云图
mp.axis("off")             # 不显示x轴、y轴下标
mp.show()
my_wordcloud.to_file("wordcloud_new.png")

在这里插入图片描述

评语文本分析小结
  • 文本可视化看到影迷的主评价词为:好看,科幻,震撼,特效剧情。
  • 从影评评价中可以看出《流浪地球》的口碑非常不错,值得一看!
项目源代码包github地址:https://github.com/Willsgao/Personal-projects/

参考网址:https://www.jianshu.com/p/d4a86da914e9
参考网址:https://blog.csdn.net/weixin_40096730/article/details/81984231
参考网址:https://blog.csdn.net/Dick633/article/details/80261233

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>