一、任务目标
本实验主要是根据导出的qq群聊天记录,做一个简单的数据提取和可视化操作,比较简单而且贴合现实生活。
二、环境以及所需的安装包
环境: win10+python3
安装包:
import re
import datetime
import matplotlib.pyplot as plt
import jieba
from wordcloud import WordCloud,STOPWORDS
import seaborn as sns
from PIL import Image
import numpy as np
三、实验过程
1.预准备
先看我们的材料:qq聊天群记录txt格式(图1);我们的目标:消息不同时段的可视化以及词云的制作(图2)


2.具体实现
先做Days和WeekDays的表格,这两者都会使用聊天信息里边时间的那一部分,写在一起比较方便。代码如下:
#做Days(天)表格
def get_date(data):
dates = re.findall(r'\d{4}-\d{2}-\d{2}',data)
days = [date[-2:] for date in dates]
plt.subplot(221)#最后的显示分为四部分,Days占第一部分
sns.countplot(days)#days就是数据集,countplot统计days每一天的重复数量就是每一天聊天数目
plt.title('Days')
#isocalendar()ISO标准化日期,返回三个值的元组(年份,星期数week number,星期几weekday)星期一为1,星期天为7
weekdays = [datetime.date(int(date[:4]),int(date[5:7]),int(date[-2:])).isocalendar()[-1] for date in dates]
plt.subplot(222)
sns.countplot(weekdays)
plt.title('WeekDays')
然后做在一天24小时的分布图,这里的思路其实和上边差不多,稍微需要注意的就是小时的表示,在导出的聊天记录里边0-9时都只有一位数,而不是像00、01、02格式,所以匹配时稍有区别,代码如下:
#一天24h的图
def get_time(data):
times = re.findall(r'\d+:\d{2}:\d{2}',data)
hours = [time.split(":")[0] for time in times]#对每一个time分割出代表小时的那部分
plt.subplot(223)
#因为qq消息导出格式里,小时0-9是以个位形式出现,所以用个位的来对应
sns.countplot(hours,order=['6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','0','1','2','3','4','5'])
plt.title("Hours")
接着是词云的制作,包括了两个函数,一个是准备data,一个是制作词云。流程就是:先匹配出消息内容,然后jieba将data分割,最后使用wordcloud制作出来。代码:
#词云制作
def get_wordcloud(text_data):
word_list = [" ".join(jieba.cut(sententce)) for sententce in text_data]
new_text = ' '.join(word_list)
#背景图片的设置,我这里设置了一个小黄人图片
pic = Image.open('123.jpg')
mang_mask = np.array(pic)
plt.subplot(224)
wordcloud = WordCloud(
background_color="white",
font_path = '/home/shen/Downloads/fonts/msyh.ttc',
mask = mang_mask,
stopwords = STOPWORDS,).generate(new_text)
plt.imshow(wordcloud)
plt.axis('off')
#匹配文本内容,调用上一个函数
def get_content(data):
pa = re.compile(r'\d{4}-\d{2}-\d{2}.*?\d+:\d{2}:\d{2}.*?\n(.*?)\n\n',re.DOTALL)
content = re.findall(pa,data)
get_wordcloud(content)
最后就是主函数调用了:
def main():
filename = "228.txt"
#encoding一下,防止乱码
with open(filename,encoding="UTF-8") as f:
data = f.read()
get_date(data)
get_time(data)
get_content(data)
plt.show()
if __name__ == '__main__':
main()