快捷搜索:  汽车  科技

简书播客(乱炖简书交友数据之代码)

简书播客(乱炖简书交友数据之代码)import pandas as pd df12 = pd.read_csv('JianShuJiaoYou-All-Data.csv' encoding='utf-8') df12.head(2) 结果如下:读取数据https://desertsx.github.io/2018/06/09/kaggle-Kernel-01/结构化数据文章配图数

上一篇文章乱炖数据之2700余篇“简书交友”专题文章数据的花式玩法发布后,不少人想学习下代码,由于此前不曾在GitHub上开源过,流程还不熟悉,再者本项目中很多尝试性的代码,异常杂乱,因而没有立马公开。在经过删减和整理后,将继续更新出来。

本文主要涉及一些结构化数据的分析,文本数据如词频统计、词云图等等。暂且跳过爬虫部分。 代码见于 GitHub - DesertsX / JianShuJiaoYou,后续LDA主题模型、word2vec词向量、文章照片爬取、人脸识别及颜值打分和照片墙等等更新后也会开源在此项目,欢迎star与指正。

另外先预告下,之后打算开个“Kaggle Kernel 学习系列”,GitHub - DesertsX / Kaggle-Kernel-Learning,主要是翻译和学习下kaggle上优秀的kernels。其中第一篇非常粗糙,还没润色、修改排版布局的notebook可供浏览下,也欢迎关注、star和提供宝贵建议:

https://desertsx.github.io/2018/06/09/1_1_Start_Here-A_Gentle_Introduction/

https://desertsx.github.io/2018/06/09/kaggle-Kernel-01/

结构化数据

文章配图数

读取数据

import pandas as pd df12 = pd.read_csv('JianShuJiaoYou-All-Data.csv' encoding='utf-8') df12.head(2)

结果如下:

Page Num Author Author_Url Title Time Read Comment Like Abstract Artical_Url Image_Url Artical_Content 0 1 0 刘秀玲 https://www.jianshu.com/u/470f33ea0c92 我要嫁这样的你 2016-07-25T12:16:39 08:00 109763 4508 5333 你不用太高,比穿三五厘米跟鞋的我看起来不矮就行。我不是小鸟依人的型,累了或者想哭的时候,我愿... https://www.jianshu.com/p/8de3d395734f ['//upload-images.jianshu.io/upload_images/125... 你不用太高,比穿三五厘米跟鞋的我看起来不矮就行。我不是小鸟依人的型,累了或者想哭的时候,我愿... 1 1 1 道长是名思维贩子 https://www.jianshu.com/u/92eb338437ee 如果你喜欢一个人,说些什么话让对方也喜欢你呢 2017-10-29T11:42:34 08:00 69260 497 3693 NaN https://www.jianshu.com/p/373d67f7cbce ['//upload-images.jianshu.io/upload_images/299... 你现在有没有喜欢一个人?

新增Images_Num一列记录每篇文章配图数,但发现数字异常,Image_Url中的每一元素是字符串而非列表。

将字符串转化成 list 格式

eval()函数:可以将 list tuple dict 与 string 相互转化

实例:

a = "[[1 2] [3 4] [5 6] [7 8] [9 0]]" print(a) print(type(a)) b = eval(a) print(b) print(type(b))

输出结果:

[[1 2] [3 4] [5 6] [7 8] [9 0]] <class 'str'> [[1 2] [3 4] [5 6] [7 8] [9 0]] <class 'list'>

统计每篇文章配图数的正确方式

def images_num(imageslist): return len(eval(imageslist)) df12['Images_Num'] = df12.Image_Url.apply(images_num) df12.head(1)

分布情况

df12.Images_Num.value_counts()

直方图

分布情况一目了然,文章配图数最多的高达80 。

df12.Images_Num.hist();

简书播客(乱炖简书交友数据之代码)(1)

文章长度 / 字数

粗略统计下每篇文章的长度

def artical_length(artical_content): return len(artical_content) df12['Artical_Length'] = df12.Artical_Content.apply(artical_length) df12.head(1) df12.Artical_Length.hist();

简书播客(乱炖简书交友数据之代码)(2)

字数与配图数

看看文章篇幅和配图数之间是否存在某种关系。

seaborn.jointplot

import seaborn as sns sns.jointplot(x="Artical_Length" y = "Images_Num" data = df12);

简书播客(乱炖简书交友数据之代码)(3)

改个参数看看

sns.jointplot(x="Artical_Length" y = "Images_Num" data = df12 kind="hex");

简书播客(乱炖简书交友数据之代码)(4)

评论数与点赞数

由皮尔逊相关系数为0.58可知,评论数与点赞数有一定的线性相关性。

sns_joinplot = sns.jointplot(x="Like" y = "Comment" data = df12); sns_joinplot.savefig('seaborn_Like_Comment_joinplot.png')

简书播客(乱炖简书交友数据之代码)(5)

阅读量、评论数与点赞数

python3d画图mpl_toolkits.mplot3d

Matplotlib 绘图教程(3D)

from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt %matplotlib inline plt.figure(figsize=(12 7)) ax1 = plt.subplot(111 projection='3d') x y z = df12['Read'] df12['Comment'] df12['Like'] ax1.scatter(x y z s=15) ax1.set_title('Read-Commnet-Like') ax1.set_zlabel('Like') ax1.set_ylabel('Comment') ax1.set_xlabel('Read') #plt.show()

简书播客(乱炖简书交友数据之代码)(6)

多变量

看看阅读量、评论数、点赞数、文章篇幅与配图数五个变量之间的相关关系。

Pairplot图

seaborn.pairplot

import matplotlib.pyplot as plt data = df12[["Read" "Comment" "Like" "Artical_Length" "Images_Num"]] #plt.figure(figsize=(6 4)) g = sns.pairplot(data palette="husl"); g.savefig('seaborn_pairplot.png')

简书播客(乱炖简书交友数据之代码)(7)

Heatmap图

seaborn-heatmap

sns.heatmap(data=data.corr() annot=True linewidths=0 vmin=-0.2 cmap='RdBu_r');

简书播客(乱炖简书交友数据之代码)(8)

sns.heatmap( data=data.corr() annot=True linewidths=0 vmin=-0.2 cmap='YlGnBu');

简书播客(乱炖简书交友数据之代码)(9)

文章发布时间

从Time列分别提取年份、月份、天、小时等等数据。

def split_time_ymd(timestamp): ymd = timestamp.split('T')[0] return ymd def split_time_year(timestamp): ymd = timestamp.split('T')[0] year = ymd.split('-')[0] return year def split_time_month(timestamp): ymd = timestamp.split('T')[0] month = ymd.split('-')[1] return month def split_time_day(timestamp): ymd = timestamp.split('T')[0] day = ymd.split('-')[-1] return day def split_time_hour(timestamp): timestamp = timestamp.split('T')[1] hour = timestamp[:2] return hour df12['YMD'] = df12.Time.apply(split_time_ymd) df12['Year'] = df12.Time.apply(split_time_year) df12['Month'] = df12.Time.apply(split_time_month) df12['Day'] = df12.Time.apply(split_time_day) df12['Hour'] = df12.Time.apply(split_time_hour) df12.head(2)

发文年份

可以和另一专题“今日看点”及一篇旧文里的数据比较:简书=鸡汤?爬取简书今日看点:1916篇热门文章可视化

df12.Year.value_counts() # 输出结果 2018 1992 2017 718 2016 6 2015 2 Name: Year dtype: int64 import matplotlib.pyplot as plt %matplotlib inline df12.Year.hist();

简书播客(乱炖简书交友数据之代码)(10)

发文月份

df12.Month.value_counts() # 输出结果 04 644 03 471 05 444 02 251 11 237 08 205 01 188 12 93 10 93 09 82 07 8 06 2 Name: Month dtype: int64 df12.Month.hist();

简书播客(乱炖简书交友数据之代码)(11)

发文日期

df12.Day.hist();

简书播客(乱炖简书交友数据之代码)(12)

发文小时

df12.Hour.hist();

简书播客(乱炖简书交友数据之代码)(13)

ECharts美颜一下:发文小时

上述绘制的发布时间的相关图表都不够美观,于是翻出压箱底的又一篇旧文:图表太丑怎么破,ECharts神器带你飞!

直接套用ECharts图表模板,改下数据和标题等参数就行了,代码参见:简书交友”专题文章之24小时分布情。

更多图表见于:ECharts3官网的个人主页

简书播客(乱炖简书交友数据之代码)(14)

年度月份分布情况

df12.groupby(['Year' 'Month']).Month.count() # 输出结果 Year Month 2015 04 1 09 1 2016 07 2 08 1 10 1 12 2 2017 01 1 02 3 04 1 06 2 07 6 08 204 09 81 10 92 11 237 12 91 2018 01 187 02 248 03 471 04 642 05 444 Name: Month dtype: int64

ECharts美颜一下:年度月份

图表太丑怎么破,ECharts神器带你飞!

ECharts3官网的个人主页

将echarts_bar_year_month.js里代码复制到该链接后刷新即可:“简书交友”专题文章之年度月份分布情况

简书播客(乱炖简书交友数据之代码)(15)

文本挖掘

相关旧文一篇:2017,那些出现在日记中的人:简单的文本挖掘

读取数据

import warnings warnings.filterwarnings("ignore") import jieba import numpy as np import codecs import pandas as pd import matplotlib.pyplot as plt %matplotlib inline import matplotlib matplotlib.rcParams['figure.figsize'] = (10.0 5.0) from wordcloud import WordCloud # https://github.com/amueller/word_cloud/ # conda install -c conda-forge wordcloud

文章内容转化成 list 格式

这段情话还不错的样子,一定是个可爱漂亮的小姐姐写的吧,逃...

content = df12.Artical_Content.values.tolist() print(len(content) '\n' content[-1]) 2718 我攒了一被子的情话,想要说给你听最近有种很杂碎的感觉,嗯...如果用比喻修辞来说的话,就是已经很久都没有那种写完满满一张纸的感觉,没有看完整整一本书的感觉,没有跑完操场一圈,没有听完一整首歌,也没有睡满整整一夜。总感觉还是缺一点什么。但我有很走心的去想了,可能是因为缺了每一个可爱的你。“如果是去见你,我会跑着去”刚看到这句话的时候,我也很赞同,因为毕竟去见一个想见了很久的人的时候,怎么也按捺不住你你内心的欣喜。到后来,当你真正去见ta的时候,你没有跑,你依然故作镇定的样子,只是你会比平时都迈的步子大一点,你担心你跑起来的样子不那么美观,你担心就算是夏天的微风也还是会把你轻薄的刘海吹乱。你会在意每个细节,你每次都希望你在ta面前是最好的状态。嗨,如果要去见你的话,我不跑着去了,我只想以我最好的状态去见你你像是我被子里的舒服你像是我右手背上的那颗痣你像是我眼角微微泛出来的光你像是我全身每一寸肌肤在呼吸你像是我枕头里的枕芯棉你像是我买过最好看书里的一页你像是我踩着云就可以飞上天你像是我走过的所有路途最想停留的瞬间你是我在夜晚闭上眼最后想到的人你是我在清晨睁开眼最先念起的人你是我的一日三餐你是我的一年四季来不及了不想再浪费时间昨天,今天,明天我还是最喜欢你总有一个人的出现,让我像流沙,像落雪。那些别人在上面划了又划的痕迹,你轻轻一抹,就平了。攒了一被子的情话,以后慢慢数给你听。希望认识更多可爱的人,一起做喜欢的事,写最纯真的字,讲有趣的故事。我是礼雪晶,那么你呢?作者:礼雪晶。“真羡慕你们这么年轻就遇到了这么才华横溢的我。”一个整天与数字对抗却藏了一被子情话的95后女生。愿你的深情不被辜负,你喜欢的人也喜欢你。

jieba 分词

segs = jieba.lcut(content[-1]) print(segs) for seg in segs: if len(seg) > 1: print(seg) # 输出结构 ['我' '攒' '了' '一' '被子' '的' '情话' ',' '想要' '说' '给' '你' '听' '最近' '有种' '很' '杂碎' '的' '感觉' ',' '嗯' '...' '如果' '用' '比喻' '修辞' '来说' '的话' ',' '就是' '已经' '很久' '都' '没有' '那种' '写' '完' '满满' '一张' '纸' '的' '感觉' ',' '没有' '看' '完' '整整' '一' '本书' '的' '感觉' ',' '没有' '跑' '完' '操场' '一圈' ',' '没有' '听' '完一' '整首歌' ',' '也' '没有' '睡满' '整整' '一夜' '。' '总' '感觉' '还是' '缺' '一点' '什么' '。' '但' '我' '有' '很' '走心' '的' '去' '想' '了' ',' '可能' '是因为' '缺' '了' '每' '一个' '可爱' '的' '你' '。' '“' '如果' '是' '去' '见' '你' ',' '我会' '跑' '着' '去' '”' '刚' '看到' '这句' '话' '的' '时候' ',' '我' '也' '很' '赞同' ',' '因为' '毕竟' '去' '见' '一个' '想见' '了' '很' '久' '的' '人' '的' '时候' ',' '怎么' '也' '按捺不住' '你' '你' '内心' '的' '欣喜' '。' '到' '后来' ',' '当' '你' '真正' '去' '见' 'ta' '的' '时候' ',' '你' '没有' '跑' ',' '你' '依然' '故作' '镇定' '的' '样子' ',' '只是' '你' '会' '比' '平时' '都' '迈' '的' '步子' '大' '一点' ',' '你' '担心' '你' '跑' '起来' '的' '样子' '不' '那么' '美观' ',' '你' '担心' '就算' '是' '夏天' '的' '微风' '也' '还是' '会' '把' '你' '轻薄' '的' '刘海' '吹乱' '。' '你' '会' '在意' '每个' '细节' ',' '你' '每次' '都' '希望' '你' '在' 'ta' '面前' '是' '最好' '的' '状态' '。' '嗨' ',' '如果' '要' '去' '见' '你' '的话' ',' '我' '不' '跑' '着' '去' '了' ',' '我' '只' '想' '以' '我' '最好' '的' '状态' '去' '见' '你' '你' '像是' '我' '被子' '里' '的' '舒服' '你' '像是' '我' '右手' '背上' '的' '那颗' '痣' '你' '像是' '我' '眼角' '微微' '泛出来' '的' '光' '你' '像是' '我' '全身' '每一寸' '肌肤' '在' '呼吸' '你' '像是' '我' '枕头' '里' '的' '枕芯' '棉' '你' '像是' '我' '买' '过' '最好' '看书' '里' '的' '一页' '你' '像是' '我' '踩' '着' '云' '就' '可以' '飞' '上天' '你' '像是' '我' '走过' '的' '所有' '路途' '最想' '停留' '的' '瞬间' '你' '是' '我' '在' '夜晚' '闭上眼' '最后' '想到' '的' '人' '你' '是' '我' '在' '清晨' '睁开眼' '最先' '念起' '的' '人' '你' '是' '我' '的' '一日三餐' '你' '是' '我' '的' '一年四季' '来不及' '了' '不想' '再' '浪费时间' '昨天' ',' '今天' ',' '明天' '我' '还是' '最' '喜欢' '你' '总有' '一个' '人' '的' '出现' ',' '让' '我' '像' '流沙' ',' '像' '落雪' '。' '那些' '别人' '在' '上面' '划' '了' '又' '划' '的' '痕迹' ',' '你' '轻轻' '一抹' ',' '就平' '了' '。' '攒' '了' '一' '被子' '的' '情话' ',' '以后' '慢慢' '数给' '你' '听' '。' '希望' '认识' '更' '多' '可爱' '的' '人' ',' '一起' '做' '喜欢' '的' '事' ',' '写' '最' '纯真' '的' '字' ',' '讲' '有趣' '的' '故事' '。' '我' '是' '礼雪晶' ',' '那么' '你' '呢' '?' '作者' ':' '礼雪晶' '。' '“' '真' '羡慕' '你们' '这么' '年轻' '就' '遇到' '了' '这么' '才华横溢' '的' '我' '。' '”' '一个' '整天' '与' '数字' '对抗' '却' '藏' '了' '一' '被子' '情话' '的' '95' '后' '女生' '。' '愿' '你' '的' '深情' '不' '被' '辜负' ',' '你' '喜欢' '的' '人' '也' '喜欢' '你' '。'] 被子 情话 想要 最近 有种 杂碎 感觉 ... 如果 比喻 修辞 来说 的话 就是 已经 很久 没有 segment = [] for line in content: try: segs = jieba.lcut(line) for seg in segs: if len(seg)>1 and seg != '\r\n': segment.append(seg) except: print(line) continue

载入停用词

words_df = pd.DataFrame({"segment": segment}) stopwords_df = pd.read_csv('Stopwords/Chinese_Stopwords.txt' index_col=False quoting=3 sep="\t" names=['stopwords'] encoding='utf-8') #quoting=3全不引用 stopwords_df.head()

去掉停用词

words_df = words_df[~words_df.segment.isin(stopwords_df.stopwords)] words_df.head()

统计词频

words_stat = words_df.groupby(by=['segment'])['segment'].agg({"计数": np.size}) words_stat = words_stat.reset_index().sort_values(by=["计数"] ascending=False) words_stat.head(30) words_stat.to_csv("JianShuJiaoYou-Words_Segments.csv" encoding='utf-8')

文章内容词云

丑版

wordcloud = WordCloud(font_path='simhei.ttf' background_color='white' max_font_size=80) word_frequence = {x[0]:x[1] for x in words_stat.head(1000).values} wordcloud = wordcloud.fit_words(word_frequence) plt.imshow(wordcloud); # plt.imsave(path)

简书播客(乱炖简书交友数据之代码)(16)

自定义背景图 1.0版

简书交友专题 Logo

简书播客(乱炖简书交友数据之代码)(17)

from scipy.misc import imread matplotlib.rcParams['figure.figsize'] = (8.0 8.0) from wordcloud import WordCloud ImageColorGenerator bimg=imread('Logo-1.jpg') wordcloud=WordCloud(background_color="white" mask=bimg font_path='simhei.ttf' max_font_size=200) word_frequence = {x[0]:x[1] for x in words_stat.head(1000).values} wordcloud=wordcloud.fit_words(word_frequence) bimgColors=ImageColorGenerator(bimg) plt.axis("off") plt.imshow(wordcloud.recolor(color_func=bimgColors));

简书播客(乱炖简书交友数据之代码)(18)

自定义背景图 2.0版

中古民谣乐团Bloody Woods

简书播客(乱炖简书交友数据之代码)(19)

from scipy.misc import imread matplotlib.rcParams['figure.figsize'] = (8.0 8.0) from wordcloud import WordCloud ImageColorGenerator bimg=imread('中古民谣乐团Bloody Woods.jpg') wordcloud=WordCloud(background_color="white" mask=bimg font_path='simhei.ttf' max_font_size=200) word_frequence = {x[0]:x[1] for x in words_stat.head(1000).values} wordcloud=wordcloud.fit_words(word_frequence) bimgColors=ImageColorGenerator(bimg) plt.axis("off") plt.imshow(wordcloud.recolor(color_func=bimgColors));

简书播客(乱炖简书交友数据之代码)(20)

还是太丑

在线词云生成网站:HTML5 Word Cloud

图表太丑怎么破,ECharts神器带你飞

本次词云实例

简书播客(乱炖简书交友数据之代码)(21)

简书播客(乱炖简书交友数据之代码)(22)

标题词频、词云

title = df12.Title.values.tolist() print(len(title) '\n' title[-1]) segment = [] for line in title: try: segs = jieba.lcut(line) for seg in segs: if len(seg)>1 and seg != '\r\n': segment.append(seg) except: print(line) continue # 2718 # 攒了一被子的情话,想说给你听 titles_df = pd.DataFrame({"segment": segment}) titles_df = titles_df[~titles_df.segment.isin(stopwords_df.stopwords)] titles_df.head() titles_stat = titles_df.groupby(by=['segment'])['segment'].agg({"计数": np.size}) titles_stat = titles_stat.reset_index().sort_values(by=["计数"] ascending=False) titles_stat.head(30) wordcloud = WordCloud(font_path='simhei.ttf' background_color='white' max_font_size=80) word_frequence = {x[0]:x[1] for x in titles_stat.head(1000).values} wordcloud = wordcloud.fit_words(word_frequence) plt.imshow(wordcloud);

简书播客(乱炖简书交友数据之代码)(23)

自定义背景图:Bloody Woods

from scipy.misc import imread matplotlib.rcParams['figure.figsize'] = (8.0 8.0) from wordcloud import WordCloud ImageColorGenerator bimg=imread('中古民谣乐团Bloody Woods.jpg') wordcloud=WordCloud(background_color="white" mask=bimg font_path='simhei.ttf' max_font_size=200) word_frequence = {x[0]:x[1] for x in titles_stat.head(1000).values} wordcloud=wordcloud.fit_words(word_frequence) bimgColors=ImageColorGenerator(bimg) plt.axis("off") plt.imshow(wordcloud.recolor(color_func=bimgColors));

简书播客(乱炖简书交友数据之代码)(24)

在线词云生成网站:HTML5 Word Cloud

本次实例

简书播客(乱炖简书交友数据之代码)(25)

简书“今日看点”专题热门文章标题词云

另一专题“今日看点”:简书=鸡汤?爬取简书今日看点:1916篇热门文章可视化

简书播客(乱炖简书交友数据之代码)(26)

简书播客(乱炖简书交友数据之代码)(27)

代码:GitHub - DesertsX / JianShuJiaoYou,后续更新LDA主题模型、word2vec词向量、文章照片爬取、人脸识别及颜值打分和照片墙等,敬请期待,欢迎star与指正。

PS:预告下,即将开启“Kaggle Kernel 学习系列”,GitHub - DesertsX / Kaggle-Kernel-Learning,欢迎star。

猜您喜欢: