本文涉及pandas和pyecharts方法库使用,re和jieba库辅助文本处理
数据来源:B站爬虫
【经典】周杰伦全MV 【193P】
之前B站的弹幕接口可以使用,后来接口更新了,得到的弹幕是乱码
新的数据接口每首歌曲最多收集一千条,旧接口可以根据日期获取弹幕数据,需要自己对xml文件中信息提取
https://comment.bilibili.com/2154849.xml (2154849是视频号bid)
导入模块包
1. 中文分词库 jieba
2. 数据分析包 pandas
3. 可视化包 matplotlib
4. 交互可视化包 pyecharts
5. 正则表达式 re
import re
import pandas as pd
from pyecharts import options as opts
from pyecharts.charts import WordCloud
import jieba
from pyecharts.globals import SymbolType
from pyecharts.charts import Grid, Line, Scatter,Pie,Bar
import matplotlib
# 显示坐标中的负号
matplotlib.rcParams["axes.unicode_minus"] = False
# 显示中文字符
matplotlib.rc("font", family="SimHei", weight="bold", size=16)
1. 数据预处理
1.1 读取数据
如果内容列存在英文逗号,使用read_csv或出现列数不符合字段数
df = pd.read_csv("./周杰伦MV.csv")
1.2 查看数据描述信息
可以看到弹幕模式列出现异常,内容列存在缺失
df.info()
1.3各列数据的含义
发表时刻 : 弹幕出现的时间以秒数为单位。
弹幕模式: 弹幕的模式1…3 滚动弹幕 4底端弹幕 5顶端弹幕 6.逆向弹幕 7精准定位 8高级弹幕
字体大小 字号, 12非常小,16特小,18小,25中,36大,45很大,64特别大
颜色 字体的颜色以HTML颜色的十进制为准
时刻 Unix格式的时间戳。基准时间为 1970-1-1 08:00:00
弹幕池 0普通池 1字幕池 2特殊池【目前特殊池为高级弹幕专用】
发送者ID 发送者的ID,用于“屏蔽此弹幕的发送者”功能
弹幕ID 弹幕在弹幕数据库中rowID 用于“历史弹幕”功能。
文件名 包含歌名和专辑名,部分歌曲是单曲
内容 弹幕内容
1.4 抽样查看数据
df.sample(5)
1.5 查看前三行数据
df.head(3)
1.6 查看后三行数据
df.tail(3)
1.7 查看重复数据
df[df.duplicated()]
1.8 清洗数据
清理数据一般涉及检验重复值,缺失值,异常值
#如果文件名和发送者ID为空,去掉该数据,同时更新df
df.dropna(inplace=True,subset=['文件名', '发送者ID'])
print(df.shape)
数据规模 (303258, 10) 303258行,10列
2. 数据提取和可视化
将pyecharts的饼图封装成一个函数 ,详细需要阅读官网:pyecharts
def GetPieFig(data:dict,title:str,width="600px",height="400px"):
"""
use pyecharts to show pie figure
-----------
data: series into dict
title: Figure title
"""
pie = (
Pie(init_opts=opts.InitOpts(width=width,height=height))
.add(title,
[[i,j] for i,j in data.items()],
center=["40%", "40%"],
radius=["30%","50%"],
label_opts=opts.LabelOpts(
is_show=True
)
)
.set_global_opts(
title_opts=opts.TitleOpts(title=title),
legend_opts=opts.LegendOpts(type_="scroll",
pos_left="80%",
orient="vertical"),
toolbox_opts=opts.ToolboxOpts(pos_bottom="10%"),
)
.set_series_opts(
label_opts=opts.LabelOpts(
formatter="{b}:{c} ({d}%)",
is_show=True
)
)
)
return pie
弹幕内容存在特殊串
def FilterWords(x):
"过滤特殊字符 只返回由中文字母数字和下划线组成的字符串"
x = str(x)
if x.startswith("[") and len(x.split(","))>6:
return x.split(",")[4][1:-1]
return " ".join(re.findall("\w+",x))
df["内容"] = df["内容"].apply(FilterWords)
2.1 专辑模块
2.1.1 文件名中提取歌名和专辑名
df["歌名"] = df["文件名"].str.extract("(\w+)")
def getAlbum(x):
m = re.search("【([\w ]+)】",x)
if m:
return m.group(1)
else:
return x
df["专辑"] = df["文件名"].apply(getAlbum)
df[["歌名","专辑"]].sample(5)
2.1.2 查看各专辑的弹幕数量(存在单曲的,只选择 1st 2nd 等开头的专辑)
不需要获取所有的列
album = df[df["专辑"].str.contains(r'^(\d)')][["发表时刻","时刻","颜色","内容","发送者ID","专辑"]] #r'^(?:531|92|541[6-9])')]
album
2.1.3 各专辑弹幕数
albumName = album["专辑"].value_counts().index.tolist()
albumCount = album["专辑"].value_counts().values.tolist()
c = (
Bar()
.add_xaxis(
albumName
)
.add_yaxis("周杰伦各专辑弹幕数",
albumCount,
)