pyecharts可视化B站弹幕

简介: pyecharts可视化B站弹幕

数据预处理


首先,查看数据集的一些信息,为了之后能够对数据集有个清晰地认识。

import pandas as pd
df = pd.read_csv('bilibili_clean.csv')
df.info()
复制代码

image.png


输出前五行。

df.head()
复制代码

image.png


通过上图可以看到, other_data 列中包含很多数据,并不是所有的数据都对后面的分析有帮助,我们将该列拆分,只保留我们需要的列。以第一行的数据为例。

'351.52700,1,25,16777215,1601686748,0,b083a745,39082825228484615'

所需数据及含义:

  • 351.52700 :弹幕的时间位置,基于视频长度,单位秒;
  • 16777215 :弹幕颜色, 16777215 对应 0xFFFFFF
  • b083a745 :弹幕发送者的用户 id
# 将other_data列进行划分,并将需要的列添加到DataFrame中
split_df = df['other_data'].str.split(',', expand=True)
column_dict = [('video_time', 0), ('color', 3), ('user_id', 6)]
for col_name, index in column_dict:
    df[col_name] = split_df[index]
# 删除other_data列
df.drop('other_data', axis=1, inplace=True)
df.head()
复制代码

image.png

这样就得到了及结构比较清晰的数据集,我们在绘制图形前,还会对数据进行的一些处理来使的图形绘制的更加方便。


弹幕长度分布条形图


添加一列 comment_length 来记录 comment 的长度,统计 comment 各长度出现的次数。使用 pyecharts 库绘制直方图。

# 添加一列comment_length来记录comment的长度
df['comment_length'] = df['comment'].map(lambda x: len(x))
length_series = df['comment_length'].value_counts()
length_series.sort_index(ascending=True, inplace=True)
# 评论长度列表(升序)
length_list = length_series.index.astype(int).tolist()
# 各长度对应出现次数列表
count_list = length_series.values.astype(int).tolist()
# 绘制直方图
from pyecharts import options as opts
from pyecharts.charts import Bar
chart = Bar()
chart.add_xaxis(length_list).add_yaxis("第一集", count_list, color='#DF0101').set_global_opts(
        title_opts=opts.TitleOpts(title="弹幕长度分布"),
        datazoom_opts=[opts.DataZoomOpts(), opts.DataZoomOpts(type_="inside")],
    ).render("弹幕长度分布.html")
chart.render_notebook()
复制代码


image.png

观察图中信息,可以看出,随着长度的增加,弹幕的数量逐渐减少,大部分弹幕长度在10以内,这也比较符合我们的习惯,笔者发弹幕一般也是就几个字。。


弹幕颜色分布饼图


首先将十进制的颜色代码转为十六进制。之后绘制彩色代码的时候就可以按照颜色代码给扇形区域绘制对应的颜色。

import time
# 将color列的数据类型由“str”转为“int”, 数据格式由“十进制”转为“十六进制”
df['color'] = df['color'].astype(int).map(lambda x: str(hex(x)))
复制代码


统计 白色弹幕彩色弹幕 的数量,绘制饼图。

# 弹幕颜色可视化
from pyecharts.charts import Pie
color_series = df['color'].value_counts()
color_list = [color for color in color_series.index]
count_list = color_series.values.astype(int).tolist()
white_other = ['白色', '彩色']
white_other_count = [count_list[0], sum(count_list[1:])]
chart = (
    Pie()
    .add(
        "",
        [list(z) for z in zip(white_other, white_other_count)],
        radius=["40%", "75%"],
    )
    .set_colors(['#0101DF', '#FE2E2E',])
    .set_global_opts(
        title_opts=opts.TitleOpts(title="普通、彩色弹幕分布饼图"),
        legend_opts=opts.LegendOpts(orient="vertical", pos_top="15%", pos_left="2%"),
    )
    .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
#     .render("pie_radius.html")
)
chart.render_notebook()
复制代码


image.png


可以看到,大部分弹幕的颜色是默认白色,虽然B站三级用户就可以发送彩色弹幕,但貌似使用的人不是很多。接下来详细看一下彩色弹幕中究竟使用的都是什么颜色? 由于颜色种类较多,这里只统计出现次数大于10次的颜色。


# 忽略出现次数小于10的颜色
for count in count_list:
    if count <= 10:
        index = count_list.index(count)
        break
new_count_list = count_list[1: index]
new_color_list = color_list[1: index]
# 将0xffffff颜色格式转为#ffffff
new_color_list = ['#' + color[2:] for color in new_color_list]
chart = (
    Pie()
    .add(
        "",
        [list(z) for z in zip(new_color_list, new_count_list)],
        radius=["40%", "75%"],
    )
    .set_colors(new_color_list)
    .set_global_opts(
        title_opts=opts.TitleOpts(title="彩色弹幕颜色分布饼图"),
        legend_opts=opts.LegendOpts(orient="vertical", pos_top="8%", pos_left="0%"),
    )
    .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
#     .render("pie_radius.html")
)
chart.render_notebook()
复制代码


image.png

哇,一眼望去五颜六色的,但仔细一看,红黄占了一大半,但这也不能够表明有这么多人喜欢红黄,通过观察手机版和网页版官方提供的色号,网页版中的色号包含 #FFFF00#FE0302,手机版的暂时无法分辨,但应该是另外两个占比较多的颜色 #FEF102E70012,这些色号使用的一方面原因是用户自身的喜爱,另一方面:官方提供色号的位置可能比较靠前(狗头保命)。

image.png


弹幕量与视频内时间关系折线图


首先将 video_time 列数据类型转换为 float,然后将视频时间(共1435秒,23:55)按照10秒为间隔进行划分,0-10,10-20,20-30,30-40... ,对应标签 10,20,30,40... 。下一步,将 “秒” 类型的数据格式转为 “分:秒” ,最后统计各时间弹幕的数量。

import numpy as np
# 将video_time列的数据类型转化为float
df['video_time'] = df['video_time'].astype('float')
# 新建一个临时的DataFrame
temp_df = pd.DataFrame({})
temp_df['video_time'] = df['video_time']
# 将video_time列按照10秒一区间进行划分。
temp_df = temp_df.apply(lambda x : pd.cut(x, list(range(0, 1435, 10)) + [np.inf], labels=list(range(0, 1435, 10))))
count_series = temp_df['video_time'].value_counts()
count_series.sort_index(ascending=True, inplace=True)
# 将time数据格式由“秒”转为“分:秒”
count_series.index = count_series.index.map(lambda x: time.strftime('%M:%S', time.gmtime(x)))
time_list = count_series.index.tolist()
count_list = count_series.values.astype('int').tolist()
复制代码


根据得到的时间列表( time_list ),弹幕数量列表( count_list )绘制折线图。

# 绘制折线图
from pyecharts.charts import Line
chart = (
    Line()
    .add_xaxis(time_list)
    .add_yaxis("第一集", count_list, is_smooth=True)
    .set_series_opts(
        areastyle_opts=opts.AreaStyleOpts(opacity=0.5),
        label_opts=opts.LabelOpts(is_show=False),
    )
    .set_global_opts(
        title_opts=opts.TitleOpts(title="弹幕量与视频时间关系"),
        datazoom_opts=[opts.DataZoomOpts(), opts.DataZoomOpts(type_="inside")],
        xaxis_opts=opts.AxisOpts(
            axistick_opts=opts.AxisTickOpts(is_align_with_label=True),
            is_scale=False,
            boundary_gap=False,
        ),
    )
#     .render("line_areastyle_boundary_gap.html")
)
chart.render_notebook()
复制代码


image.png

根据视频内各个时间段发送的弹幕量,可以大致得出视频的高能时刻,就和“精彩时刻”差不多。图中峰值主要出现在开始,中间,结尾,也比较符合一般人发弹幕的时间点。


弹幕发送次数饼图


统计单用户发送弹幕次数,将弹幕发送次数分为四类,1次,2次,3次,>3次,并绘制弹幕发送次数饼图。


# 获取用户id(index)与发送弹幕次数(values)组成的series
series_user = df['user_id'].value_counts()
# 获取发送弹幕次数(index)与用户数量(values)组成的series
series_comment = series_user.value_counts()
# 对index按照升序排序
series_comment.sort_index(ascending=True, inplace=True)
# 发送弹幕次数列表
comment_count_list = series_comment.index
# 用户数量列表
user_count_list = series_comment.values.tolist()
# 将弹幕次数分为4类, 1次,2次,3次,大于3次
comment_count_list = [str(count) + '次' for count in comment_count_list[:3]] + ['>3次']
user_count_list = user_count_list[:3] + [sum(user_count_list[3:])]
chart = (
    Pie()
    .add(
        "",
        [list(z) for z in zip(comment_count_list, user_count_list)],
        center=["35%", "50%"],
    )
    .set_global_opts(
        title_opts=opts.TitleOpts(title="弹幕发送次数分布饼图"),
        legend_opts=opts.LegendOpts(pos_left="80%", orient="vertical"),
    )
    .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
#     .render("pie_position.html")
)
chart.render_notebook()
复制代码

image.png


根据图中可以看到,发送一条弹幕的人占了大部分,2条的有5222个用户,3条1681个用户,大于3条的有1873个用户,接下来具体看看弹幕数量 Top10


单用户弹幕数量Top10直方图


top10 = series_comment[-10:].index.tolist()
top10.reverse()
chart = (
    Bar()
    .add_xaxis(list(range(1, 11)))
    .add_yaxis('第一集', top10, color='#F781D8')
    .set_global_opts(
        title_opts=opts.TitleOpts(title="用户发送弹幕数Top10"),
        datazoom_opts=opts.DataZoomOpts(type_="inside"),
    )
#     .render("bar_datazoom_inside.html")
)
chart.render_notebook()
复制代码

image.png

牛!!排名第一的用户,在23分钟发了76条弹幕。。平均20秒左右一条,不得不说,真的厉害,这还能够好好看视频么。不过可能是看完一遍,之后再卡时间点发弹幕的。


弹幕热词分析词云图


首先加载本地停用词库,这里根据弹幕中的词汇手动添加了一些的停用词,为了词云图的效果更好一点。

def load_stopwords(read_path):
    '''
    读取文件每行内容并保存到列表中
    :param read_path: 待读取文件的路径
    :return: 保存文件每行信息的列表
    '''
    result = []
    with open(read_path, "r", encoding='utf-8') as f:
        for line in f.readlines():
            line = line.strip('\n')  # 去掉列表中每一个元素的换行符
            result.append(line)
    return result
# 加载中文停用词
stopwords = load_stopwords('wordcloud_stopwords.txt')
复制代码


现在对弹幕中的数据进行清洗,主要去除弹幕中的空格,重复单一字符(‘111’,‘aaa’),以及时间(某某打卡)等,之后删除空字符串。

# 去除弹幕中的空格
df['comment'] = df['comment'].str.replace(r' ', '')
# 用空字符串('')替换('111','aaa','....')等
df['comment'] = df['comment'].str.replace(r'^(.)\1*$', '')
# 用空字符串('')替换('2020/11/20 20:00:00')等
df['comment'] = df['comment'].str.replace(r'\d+/\d+/\d+ \d+:\d+:\d+', '')
# 将空字符串转为'np.nan',即NAN,用于下一步删除这些弹幕
df['comment'].replace(to_replace=r'^\s*$', value=np.nan, regex=True, inplace=True)
# 删除comment中的空值,并重置索引
df = df.dropna(subset=['comment'])
df.reset_index(drop=True, inplace=True)
复制代码


清洗后,就可以使用 jieba 分词对弹幕进行分词,但分词前最好先使用 load_userdict() 导入本地的自定义词典,针对特有的领域词可以进行保留,不对其进行分词,之后剔除分词后的停用词。

import jieba
# 添加自定义词典
jieba.load_userdict("自定义词典.txt")
token_list = []
# 对弹幕内容进行分词,并将分词结果保存在列表中
for comment in df['comment']:
    tokens = jieba.lcut(comment, cut_all=False)
    token_list += [token for token in tokens if token not in stopwords]
len(token_list)
复制代码
119752


统计得到的词汇列表,取出现次数最多的前100个词,绘制词云图。

from pyecharts.charts import WordCloud
from collections import Counter
token_count_list = Counter(token_list).most_common(100)
new_token_list = []
for token, count in token_count_list:
    new_token_list.append((token, str(count)))
chart = (
    WordCloud()
    .add(series_name="热词", data_pair=new_token_list, word_size_range=[12, 88])
    .set_global_opts(
        title_opts=opts.TitleOpts(
            title="弹幕热点词云图", title_textstyle_opts=opts.TextStyleOpts(font_size=23)
        ),
        tooltip_opts=opts.TooltipOpts(is_show=True),
    )
#     .render("basic_wordcloud.html")
)
chart.render_notebook()
复制代码

image.png

刚开始绘制词云图时效果可能不太好,需要手动添加了一些词。现在看起来就还挺不错的。



相关文章
|
7月前
|
数据可视化 Python
百度搜索:蓝易云【使用Python的数据可视化库Matplotlib实现折线图教程。】
通过Matplotlib的丰富功能,你可以进一步自定义折线图,例如添加图例、设置线条样式、修改坐标轴范围等。希望这个教程对你有所帮助,如果有任何进一步的疑问,请随时提问。
173 0
|
12天前
|
数据可视化 搜索推荐 Shell
Python与Plotly:B站每周必看榜单的可视化解决方案
Python与Plotly:B站每周必看榜单的可视化解决方案
|
2月前
|
数据可视化 数据挖掘 Python
Seaborn 库创建吸引人的统计图表
【10月更文挑战第11天】本文介绍了如何使用 Seaborn 库创建多种统计图表,包括散点图、箱线图、直方图、线性回归图、热力图等。通过具体示例和代码,展示了 Seaborn 在数据可视化中的强大功能和灵活性,帮助读者更好地理解和应用这一工具。
42 3
|
7月前
|
搜索推荐 数据可视化 Python
Matplotlib进阶:打造个性化图表
【4月更文挑战第17天】本文介绍了如何使用Matplotlib进阶功能创建个性化图表,包括自定义样式表、制作动画、实现交互式图表及整合外部库。通过`plt.style.use()`可切换样式表,自定义图表样式;利用`FuncAnimation`模块可创建动画图表展示数据变化;启用交互模式配合事件处理函数,使图表响应鼠标操作;结合Seaborn和Plotly扩展Matplotlib功能,提升图表质量和交互性。这些技巧能帮助你打造更专业、更具吸引力的数据可视化作品。
|
7月前
|
数据采集 自然语言处理 数据可视化
怎么使用Pyecharts库对淘宝数据进行可视化展示
怎么使用Pyecharts库对淘宝数据进行可视化展示
112 0
|
7月前
|
数据采集 JSON API
使用Python获取B站视频并在本地实现弹幕播放功能
使用Python获取B站视频并在本地实现弹幕播放功能
139 0
|
数据可视化 Ubuntu 数据挖掘
Python绘制精美可视化数据分析图表(一)-Matplotlib
数据分析是指用适当的统计分析方法对收集来的大量数据进行分析,提取有用信息和形成结论而对数据加以详细研究和概括总结的过程.这一过程也是质量管理体系的支持过程.在实用中,数据分析可帮助人们作出判断,以便采取适当行动 在DT时代,数据分析是企业做出重要决策的基础,巧妇难为无米之炊,数据就是米,是数据分析基础中的基础,但是没有经过整理的数据,或许杂乱无章,没有任何意义,通过数据分析相关手段处理之后,让数据变得有意义,特别是整理后的数据经过可视化,更加直观,更容易,快速地找到问题所在,更有利于做出正确的决策,不至于在市场经营中处于被动局面.所以数据可视化也是我们数据分析中最重要的工具,也是最重要的一环
445 1
|
监控 数据可视化 JavaScript
内网控制软件的数据可视化:使用D3.js创建交互式图表
在现代企业中,数据管理和可视化变得至关重要。内网控制软件的用户权限管理和监控是确保安全性的关键部分。但如何有效地管理和可视化数据呢?本文将介绍如何使用D3.js创建交互式图表,以实现内网控制软件的数据可视化。
211 1
|
数据采集 数据可视化 Go
使用Pyecharts对猫眼电影票房可视化分析
使用Pyecharts对猫眼电影票房可视化分析
|
数据可视化 BI 数据处理
Pandas + Pyecharts | ADX游戏广告投放渠道综合分析
Pandas + Pyecharts | ADX游戏广告投放渠道综合分析