豆瓣电影(二):数据分析

豆瓣电影数据分析需要用到的数据文件 —> 豆瓣高分电影文件链接:https://pan.baidu.com/s/18cYvdphVOI7vT6PynDrmDA
提取码:421y

一、数据集

  豆瓣高分电影.xlsx数据集文件:
在这里插入图片描述

1.1、导入三个基础库

  Pandas: Pandas是一个强大的分析结构化数据的工具集;它的使用基础是Numpy(提供高性能的矩阵运算);用于数据挖掘和数据分析,同时也提供数据清洗功能。
  Numpy: NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
  Matplotlib: Matplotlib 是一个 Python 的 2D绘图库,它以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形。

  这三个第三方库较大,pip install 第三方库名,下载的同时网络慢的小伙伴无需着急,因为pip默认使用的源为官方源,即国外的源。所以可以更换国内源来提升下载速度。例如

https://pypi.tuna.tsinghua.edu.cn/simple/ 清华
http://pypi.doubanio.com/simple/ 豆瓣
http://mirrors.aliyun.com/pypi/simple/ 阿里
https://pypi.mirrors.ustc.edu.cn/simple/ 中国科学技术大学
http://mirrors.163.com/pypi/simple/ 网易

import pandas as pd		# pip install pandas
import numpy as np		# # pip install numpy
import matplotlib as mpl 

1.2、忽略警告

  有时候运行代码时会有很多warning输出,如提醒新版本之类的等等,这不是报错,程序依然能往下运行。此时就可以使用warnings模块利用过滤器来实现忽略警告信息。

import warnings
warnings.filterwarnings('ignore')   # 不发出警告

1.3、设置字体和样式

import matplotlib as mpl
import matplotlib.style as psl

# 设置字体
mpl.rcParams['font.sans-serif'] = ['SimHei']
psl.use('ggplot')       # 样式

二、数据清洗

  基本概念: 数据清洗(Data cleaning)– 对数据进行重新审查和校验的过程,目的在于删除重复信息、纠正存在的错误,并提供数据一致性。

  导出数据: 从数据集“豆瓣高分电影.xlsx”文件中将数据提取出来。
  pd.read_csv:导出csv文件。
  pd.read_excel:导出Excel文件。
  pd.read_json:导出json文件。
  。。。等等

# 导出数据
data = pd.read_excel('豆瓣高分电影.xlsx',sheet_name='movie')     # sheet_name选择簿名

data.head(n): 查看数据前n行,不加n 即查看数据前五行。
data.tail(n): 查看数据后n行,不加n 即查看数据后五行。

print(data.head())      =
print(data.tail())

代码执行结果为:
在这里插入图片描述

2.1、缺失值

data.isnull(): 查看数据的空值:
axis=0与axis=1区别:
  使用0值表示沿着每一列或行标签/索引值向下执行方法,即沿着垂直的方向对行进行“操作;”
  使用1值表示沿着每一行或者列标签横向执行对应的方法,即沿着水平的方向对列进行“操作”。
np.sum(): 即numpy.sum(),其功能为数组沿着指定的轴求和。

# 查看缺失值
nulls = np.sum(data.isnull(),axis=0)
print(nulls)

代码执行结果,无空值缺失值。
在这里插入图片描述
若存在缺失值,dropna()删除掉即可。

# 删除缺失值
drop_ndata = data.dropna()
print(drop_ndata)

2.2、电影类型

  对指定列电影类型进行数据清洗,以达到绘图效果标准的数据。这里定义clean_type函数,传入数据以及指定列。通过第三方库jieba对数据进行分词。

2.2.1、jieba简介与安装

简介: jieba库是一个进行中文分词的第三方库。可用来进行关键字搜索。
安装: 在终端Python环境下输入:pip install jieba 进行下载;亦可在pycharm左下角的Terminal进入终端输入:pip install jieba下载。

  由于小编这里已经下载过了,则显示如下:
在这里插入图片描述

2.2.2、jieba三种分词模式

精确模式: 试图将句子最精确地切开,适合文本分析(默认是精确模式);
全模式: 把句子中所有的可以成词的词语都扫描出来, 速度非常快,有冗余,不能解决歧义;
搜索引擎模式: 在精确模式的基础上,对长词再次切分,适合用于搜索引擎分词。

import jieba
#精确模式(cut_all参数值为False表示精确模式)
accurate = jieba.cut("我遁着岁月的足迹,走过散落一地的旖旎,寻找流年深处的一季花雨。",cut_all=False)
print( "精确模式:","-".join(accurate))

#全模式(cut_all参数值为True表示全模式)
alls = jieba.cut("我遁着岁月的足迹,走过散落一地的旖旎,寻找流年深处的一季花雨。",cut_all=True)
print( "全模式:","-".join(alls))

#搜索引擎模式(粒度比较细)
search = jieba.cut_for_search("我遁着岁月的足迹,走过散落一地的旖旎,寻找流年深处的一季花雨。")
print("搜索引擎模式:","-".join(search))

代码执行结果:

精确模式:---岁月--足迹--走过-散落-一地--旖旎--寻找---深处--一季-花雨-。
全模式:---岁月--足迹--走过-散落----旖旎--寻找-流年-深处--一季---。
搜索引擎模式:---岁月--足迹--走过-散落-一地--旖旎--寻找---深处--一季-花雨-

 对电影类型进行数据清洗。
jieba.lcut(): 得到列表型数据的分词结果

'''清洗分词电影类型数据'''
def clean_type(df,loc):
    '''
    :param df: 传入的数据
    :param loc: 传入的列名
    :return: 返回清洗好的数据
    '''
    movie_types = df[loc].tolist()
    movie_sub = [i.replace('/', '') for i in movie_types]  # 列表推导式将 / 替换成空字符
    movie_join = ''.join(movie_sub)     # join合并成字符串数据

    # jieba.lcut得到列表型数据的分词结果
    list_lcut = jieba.lcut(movie_join)
    df_clean = pd.DataFrame(list_lcut, columns=[loc])   # pandas转化

    return df_clean

if __name__ == '__main__':
    print(drop_ndata['电影类型'])   # 查看原数据
    movie_type = clean_type(drop_ndata,'电影类型')
    print(movie_type)              # 查看清洗后的数据

代码输出结果:
在这里插入图片描述

三、绘图

3.1、参数了解

value_counts(): 对每个值计算有多少个重复值;
tolist(): 对指定列转化为列表数据;
figsize(): 设置画布大小;
color: 设置颜色;
alpha: 设置透明度;
fontsize: 设置字体大小;
plt.title(): 设置标题;
plt.legend(): 设置图例;
plt.grid(): 设置网格;
plt.text(): 设置文本注释;
plt.savefig(): 保存图片;
plt.show(): 展示绘画;


3.2、条形折线图

  绘制排名前十上映年份的电影数量。按电影数量排序,而不是按年份的高低。

  提取上映日期里的年份,value_counts()对年份计算重复值

pub_time = drop_ndata['上映日期'].str[:4].value_counts()[:15]

   绘制TOP10电影上映年份——条形折线图

 # 绘制TOP10电影上映年份—条形折线图
 # 提取前十上映日期年份并统计个数
 pub_time = drop_ndata['上映日期'].str[:4].value_counts()[:15]
 x = pub_time.index.tolist()     # 年份作为x轴
 y = pub_time.values.tolist()    # 个数作为y轴

 fig1 = plt.figure(num=1, figsize=(12,6))  # 创建第一个图  figsize画布大小
 plt.bar(range(len(x)), y, tick_label=x, facecolor='#844200', width=0.7, alpha=0.8)      # 条形
 plt.plot(x, y, '-->',color='#613030',alpha=0.8)     # 折线
 plt.ylabel('个数', fontsize=13)       # y轴标签
 plt.title('TOP10电影上映年份',color='#613030',fontsize=14)   # 标题
 plt.legend(['上映年份'])    # 图例
 plt.grid(True)  # 网格
 # 文本注释
 for i, j in zip(x, y):
     plt.text(i, j+0.5, '%.0f' % j, ha='center', fontsize=11)
 # 保存图片
 plt.savefig('TOP10电影上映年份-条形折线图.png')
 plt.show()      # 展示

代码执行结果:
在这里插入图片描述

3.3、水平条形图

计算前十导演拍摄的电影数,绘制导演-水平条形图

# 绘制导演-水平条形图
# 计算前十导演拍摄的电影数
director = drop_ndata['导演'].value_counts()[:10]

director_y = director.index.tolist()     # 导演作y轴
director_x = director.values.tolist()    # 拍摄的电影个数作x轴

fig2 = plt.figure(num=2, figsize=(15,8))  # 创建第二个图
#   facecolor颜色     tick_label:y轴名
b = plt.barh(y=director_y, width=director_x, tick_label=director_y, facecolor='#CF9E9E')
plt.yticks(rotation=25,fontsize=12)  # 使x轴字体倾斜55度
plt.xlabel('拍摄的电影个数', fontsize=15)
plt.legend(['导演'])    # 图例
plt.title('导演排名', fontsize=15,color='#613030')
#为横向水平的柱图右侧添加数据标签。
for rect in b:
    w = rect.get_width()
    plt.text(w, rect.get_y()+rect.get_height()/2, '%d' %int(w), ha='left', va='center',fontsize=11)

# 保存图片
plt.savefig('导演排名-水平条形图.png')
plt.show()  # 展示

代码执行结果:
在这里插入图片描述

3.4、饼状图

 利用前面clean_type函数清洗好的电影类型列数据,计算前十的电影类型占比,绘制饼状图。
  plt.axis(‘equal’): 避免比例压缩为椭圆
  explode: 指定分离哪一块区域

# 绘制电影类型-饼图
fig2 = plt.figure(num=3,figsize=(10,6))  # 创建第三个图
movie_type = clean_type(drop_ndata,'电影类型')
# print(movie_type)
# 计算前十电影类型数量
counts = movie_type['电影类型'].value_counts()[:10]

x = counts.index.tolist()  # 电影类型
y = counts.values.tolist()  # 个数
# 电影类型占比
movie_type_pro = list(map(lambda i:i/np.sum(y),y))      # lambda匿名函数
fig3 = plt.figure(num=3, figsize=(10, 6))  # 创建第二个图
explode = [0, 0.1, 0, 0, 0, 0, 0, 0, 0, 0]  # 指定分离哪一块区域
color = ['#737300','#0066CC','#00E3E3','#006030','#AE0000', '#FFA500', '#EA7500', '#AE00AE', '#696969','#984B4B']  # 定义饼图区域颜色

# %.2f%%:表示小数点后2位,如有要小数点后几位就改成几
plt.pie(movie_type_pro, labels=x, autopct='%.2f%%', colors=color, explode=explode, shadow=True)  # shadow=True设置阴影特效
plt.title('TOP10电影类型占比', fontsize=15)  # 标题
plt.legend(x, fontsize=14)
plt.axis('equal')
plt.savefig('TOP10电影类型占比-饼状图.png')
plt.show()

代码执行结果为:
在这里插入图片描述

3.5、折线图

  按电影评分排序,绘制高分电影——折线图。
  sort_values(): Pandas排序函数,将数据集依照某个字段中的数据进行排序,该函数即可根据指定列数据也可根据指定行的数据排序。
  ascending: 等于False为降序排序,等于True为升序排序。

# 绘制高分电影-折线图
# 索引提取
movie_locs = drop_ndata.loc[:, ['电影名', '电影评分']]
movie_sorts = movie_locs.sort_values('电影评分', ascending=False)[:20]  # 按电影评分降序排序

x = movie_sorts['电影名'].tolist()  # 电影名称做x轴
y = movie_sorts['电影评分'].tolist()  # 电影评分做y轴

fig1 = plt.figure(num=4, figsize=(13, 8))  # 创建第四个图  figsize画布大小
# 美化样式(dark_background、bmh、grayscale、ggplot、fivethirtyeight,seaborn)
plt.style.use('fivethirtyeight')
plt.plot(x, y, '--o',color='#BB5E00')
plt.xticks(rotation=35, fontsize=12)  # 使x轴字体倾斜35度
plt.ylabel('电影评分', fontsize=13)
plt.title('TOP5豆瓣高分电影', fontsize=15,color='#BB5E00')
plt.legend(['电影名'])  # 图例
plt.grid(True)  # 网格
# 文本
for i, j in zip(x, y):
    plt.text(i, j + 0.005, '%.1f' % j, ha='center', fontsize=11)
plt.savefig('TOP5豆瓣高分电影-折线图.png')
plt.show()

代码执行结果为:
在这里插入图片描述

3.6、词云

  使用结巴分析对电影简介进行提取标签,利用wordcloud库执行绘制电影简介——词云图。

  导入相关库。

import jieba.analyse                    # 结巴分析
from wordcloud import WordCloud
from matplotlib.image import imread         # 读取图片
from wordcloud import ImageColorGenerator   # 获取图片像素值

  to_file(): 保存图片。
  plt.axis(“off”): 不显示坐标尺寸。
  mask: 设置词云模板图片。
  font_path: 设置字体,路径一般为c:\windows\Fonts\simhei.ttf。
  background_color="": 设置图片的背景颜色。

  词云模板图片为:
在这里插入图片描述

# 绘制电影简介-词云图
text = drop_ndata['电影简介'].tolist()  # 转化为列表数据
text_join = ''.join(text)  # join将列表数据合并成字符串数据
re_sub = re.sub(r'[\n\s\t]', '', text_join)  # re.sub将空行空白字符替换掉

back_img = imread("虎.jpg")  # 读取图片模板
img_colors = ImageColorGenerator(back_img)       # 生成图片的像素值

# 第一个参数:待提取关键词的文本
# 第二个参数:返回关键词的数量,重要性从高到低排序
# 第三个参数:是否同时返回每个关键词的权重
# 第四个参数:词性过滤,为空表示不过滤,若提供则仅返回符合词性要求的关键词,allowPOS=('ns', 'n', 'vn', 'v')表示选取地名、名词、动名词、动词
tags = jieba.analyse.extract_tags(re_sub, topK=1000, withWeight=True, allowPOS=())  # 使用结巴分析提取标签
cloud_data = {item[0]: item[1] for item in tags}  # tags是数组形式,把数组转为词频字典

word_cloud = WordCloud(font_path="c:\windows\Fonts\simhei.ttf",  # 字体,本电脑c盘下的黑体,这样才能显示中文
                       background_color="white",  # 图片的背景颜色
                       max_words=500,  # 字体个数,不超过上面选取的个数
                       max_font_size=35,  # 字体大小
                       width=2500,  # 图片像素宽
                       mask=back_img,  # 使用图片蒙板,上面读取图片的像素
                       height=1080).generate_from_frequencies(cloud_data)  # 传入上面的词频结果

sub_color = word_cloud.recolor(color_func=img_colors)  # 替换默认的字体颜色
plt.figure(figsize=(25,25))  # 创建一个图形实例,设置画布大小
plt.imshow(sub_color, interpolation='bilinear')  # 插值='双线性'
plt.axis("off")  # 不显示坐标尺寸
word_cloud.to_file('电影简介-词云.png')  # 保存图片
plt.show()

代码执行结果为:
在这里插入图片描述

4、项目总结

  此次项目仅为简单的数据分析,没有涉及到机器学习算法之类的分析数据。学习了解数据分析三大基础库pandas、numpy与matplotlib结合使用。

  若有小伙伴有疑惑的地方,可在评论区留言,小编看到会尽快一一回复;此项目有需要改进的地方,也请大佬不吝赐教,感谢!

注:本项目仅用于学习用途,若用于商业用途,请自行负责!!

猜你喜欢

转载自blog.csdn.net/weixin_45032666/article/details/108339858