数据分析学习——学术前沿趋势分析 任务3(论文代码统计)
作者:互联网
数据分析学习——学术前沿趋势分析 任务3
任务3: 论文代码统计
3.1 任务说明
- 任务主题:论文代码统计,统计所有论文出现代码的相关统计;
- 任务内容:使用正则表达式统计代码连接、页数和图表数据;
- 任务成果:学习正则表达式统计;
3.2 数据处理步骤
在原始arxiv数据集中作者经常会在论文的comments
或abstract
字段中给出具体的代码链接,所以我们需要从这些字段里面找出代码的连接。
- 确定数据出现的位置;
- 使用正则表达式完成匹配;
- 完成相关的统计;
3.3 知识点详解
3.3.1 正则表达式
正则表达式(Regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
3.3.1.1 普通字符
大写和小写字母、所有数字、所有标点符号和一些其他符号。
字符 | 描述 |
---|---|
[ABC] | 匹配 […] 中的所有字符,例如 [aeiou] 匹配字符串 “google runoob taobao” 中所有的 e o u a 字母。 |
[^ABC] | 匹配除了 […] 中字符的所有字符,例如 [^aeiou] 匹配字符串 “google runoob taobao” 中除了 e o u a 字母的所有字母。 |
[A-Z] | [A-Z] 表示一个区间,匹配所有大写字母,[a-z] 表示所有小写字母。 |
. | 匹配除换行符(\n、\r)之外的任何单个字符,相等于 [^\n\r]。 |
[\s\S] | 匹配所有。\s 是匹配所有空白符,包括换行,\S 非空白符,包括换行。 |
\w | 匹配字母、数字、下划线。等价于 [A-Za-z0-9_] |
3.3.1.2 特殊字符
有特殊意义的字符。
特别字符 | 描述 |
---|---|
( ) | 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 ( 和 )。 |
* | 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 *。 |
+ | 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +。 |
. | 匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 . 。 |
[ | 标记一个中括号表达式的开始。要匹配 [,请使用 [。 |
? | 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 ?。 |
\ | 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, ‘n’ 匹配字符 ‘n’。’\n’ 匹配换行符。序列 ‘’ 匹配 “”,而 ‘(’ 则匹配 “(”。 |
^ | 匹配输入字符串的开始位置,除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配 ^ 字符本身,请使用 ^。 |
{ | 标记限定符表达式的开始。要匹配 {,请使用 {。 |
| | 指明两项之间的一个选择。要匹配 |,请使用 |。 |
3.3.1.3 限定符
字符 | 描述 |
---|---|
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,‘zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。 |
? | 匹配前面的子表达式零次或一次。例如,“do(es)?” 可以匹配 “do” 、 “does” 中的 “does” 、 “doxy” 中的 “do” 。? 等价于 {0,1}。 |
{n} | n 是一个非负整数。匹配确定的 n 次。例如,‘o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。 |
{n,} | n 是一个非负整数。至少匹配n 次。例如,‘o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。‘o{1,}’ 等价于 ‘o+’。‘o{0,}’ 则等价于 ‘o*’。 |
{n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,“o{1,3}” 将匹配 “fooooood” 中的前三个 o。‘o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格。 |
3.3.2 DataFrame数据集使用注意事项
若要对不同特征进行统计、筛选,每一次筛选时应在新建的原始数据集副本上进行,培养使用df1 = df.copy()的习惯,避免在切片、筛选等操作过程中改变原始数据集,从而影响统计结果。
3.4 具体代码实现
import os #操作和处理文件路径
import pandas as pd #处理数据,数据分析
import matplotlib.pyplot as plt
import json
from bs4 import BeautifulSoup
import seaborn as sns
import requests
import re
os.chdir("D:\数据分析\Datawhale项目")
data_all = []
#使用with语句优势:1、自动关闭文件句柄;2、自动显示(处理)文件读取数据异常
with open ("arxiv-metadata-oai-2019.json",'r') as f:
for line in f:
d = json.loads(line)
#提取与本次相关的三列数据"abstract","categories","comments"
d = {'title':d['title'],'abstract':d['abstract'],'categories':d['categories'],'comments':d['comments']}
data_all.append(d)
data_all = pd.DataFrame(data_all)
data_p = data_all.copy()
data_all.shape
(170618, 4)
3.4.1 统计论文页数情况
首先统计论文页数,也就是在comments
字段中抽取pages和figures。
对pages进行抽取:
# 使用正则表达式匹配各论文页数
data_p['pages'] = data_p['comments'].apply(lambda x: re.findall('[1-9][0-9]* pages', str(x)))
# 筛选出有页数信息的论文
data_p = data_p[data_p['pages'].apply(len) > 0]
# 将页数数据格式由str转为int
data_p['pages'] = data_p['pages'].apply(lambda x: int(x[0].replace(' pages', '')))
#查看含有页数信息的数据数量
print(data_p.shape)
(80696, 5)
对pages进行统计:
# 画图查看有页数信息和无页数信息论文的比例
# 支持中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']# 字体
plt.figure(figsize = (10,8))
plt.pie(x=[80696,170618-80696],labels=['有页数数据','无页数数据'],autopct='%.1f%%',startangle= 60,textprops={'fontsize': 16, 'color': 'black'})
plt.title('有页数数据占比',fontsize=24)
#添加具体数值标签
plt.text(-0.6,0.15,80696,fontsize= 14)
plt.text(0.4,-0.55,89922,fontsize= 14)
plt.show()
data_p['pages'].describe().astype(int)
count 80696
mean 18
std 20
min 1
25% 9
50% 14
75% 24
max 1958
Name: pages, dtype: int32
#页数最多的论文信息
data_p[data_p['pages'] == 1958]
title | abstract | categories | comments | pages | |
---|---|---|---|---|---|
36389 | The (High Quality) Topological Materials In Th... | "Topological Quantum Chemistry (TQC) links t... | cond-mat.mtrl-sci | 1958 pages and 4989 figures. New Version, seve... | 1958 |
接下来按照分类统计论文页数,选取了论文的第一个类别的主要类别:
#选择主要类别
data_p['categories']= data_p['categories'].apply(lambda x:x.split(' ')[0])
data_p['categories']= data_p['categories'].apply(lambda x:x.split('.')[0])
#每类论文的平均页数图形化
plt.figure(figsize = (12,6))
data_p.groupby(['categories'])['pages'].mean().plot(kind='bar')
plt.title('各主要类别的平均页数',fontsize=20)
#给图形增加标签
#x1 = list(range(0,31))
x1 = []
for i in range(0,31):
x1.append(i-0.5)
y1 = data_p.groupby(['categories'])['pages'].mean().tolist()
for x,y in zip(x1,y1):
plt.text(x,y+0.8,'%0.2f'%y,verticalalignment='center',fontsize = 8)
统计结果如下:
- 数据集中含有页数信息的论文数目为80696,占整个数据集比重47.3%;
- 含有页数信息的论文平均页数为18页;
- 在含有页数信息的数据样本中,75%的论文在24页以内,50%的论文在14页以内;
- 页数最多的论文有1958页,详细信息见上文输出结果;
- 在含有页数信息的数据样本中,平均页数最多的论文为28.62页,论文类别为econ(经济学);
3.4.2 对论文图标进行统计
接下来对论文图表个数进行抽取:
data_pic = data_all.copy()
data_pic['figures'] = data_pic['comments'].apply(lambda x: re.findall('[1-9][0-9]* figures', str(x)))
data_pic = data_pic[data_pic['figures'].apply(len) > 0]
data_pic['figures'] = data_pic['figures'].apply(lambda x: float(x[0].replace(' figures', '')))
data_pic.shape
(51439, 5)
data_pic['figures'].describe()
count 51439.000000
mean 7.943195
std 23.148960
min 1.000000
25% 4.000000
50% 6.000000
75% 10.000000
max 4989.000000
Name: figures, dtype: float64
# 画图查看有页数信息和无页数信息论文的比例
# 支持中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']# 字体
plt.figure(figsize = (10,8))
plt.pie(x=[51439,119179],labels=['有图表个数数据','无图表个数数据'],autopct='%.1f%%',startangle= 60,textprops={'fontsize': 16, 'color': 'black'})
plt.title('有图表个数数据占比',fontsize=24)
#添加具体数值标签
plt.text(-0.35,0.4,51439,fontsize= 14)
plt.text(0.13,-0.7,119179,fontsize= 14)
plt.show()
#选择主要类别
data_pic['categories']= data_pic['categories'].apply(lambda x:x.split(' ')[0])
data_pic['categories']= data_pic['categories'].apply(lambda x:x.split('.')[0])
#每类论文的平均图表数目图形化
plt.figure(figsize = (12,6))
data_pic.groupby(['categories'])['figures'].mean().plot(kind='bar')
plt.title('各主要类别论文的平均图表数',fontsize=20)
#给图形增加标签
#x1 = list(range(0,31))
x1 = list(range(0,24))
y1 = data_pic.groupby(['categories'])['figures'].mean().tolist()
for x,y in zip(x1,y1):
plt.text(x,y+0.4,'%0.2f'%y,ha='center',fontsize = 8)
统计结果如下:
- 含有图表信息的论文共51439篇,占整个数据集30.1%;
- 含有图表信息的论文平均每篇论文含有8个图(表);
- 在含有图表信息的数据样本中,50%的论文包含6个图(表),75%的论文包含10个图(表);
- 图表数目最多的论文包含4898个图表;
- 在含有图表信息的数据样本中,平均含有图表数最高的类别为q-aig(量子代数与拓扑),图(表)数目为21个。
3.4.3 统计GitHub代码连接数目
最后对论文的代码连接进行提取,为简化任务我们只抽取github链接,选取了论文的第一个类别的主要类别::
#选择论文分类的第一类别
data_with_code = data_all.copy()
data_with_code['categories']= data_with_code['categories'].apply(lambda x:x.split(' ')[0])
data_with_code['categories']= data_with_code['categories'].apply(lambda x:x.split('.')[0])
#筛选包含github的论文
data_with_code = data_with_code[data_with_code.comments.str.contains('github')== True
|(data_with_code.abstract.str.contains('github')==True)]
data_with_code['text']= data_with_code['abstract'].fillna('') + data_with_code['comments'].fillna('')
data_with_code.shape
(1000, 5)
#使用正则表达式匹配论文
pattern = '[a-zA-Z]+://github[^\s]*' #需要一个解释
data_with_code['code_flag']= data_with_code['text'].str.findall(pattern).apply(len)
data_with_code['code_flag'].describe()
count 1000.00000
mean 0.97500
std 0.56453
min 0.00000
25% 1.00000
50% 1.00000
75% 1.00000
max 4.00000
Name: code_flag, dtype: float64
data_with_code = data_with_code[data_with_code['code_flag'] >= 1]
plt.figure(figsize=(12, 6))
data_with_code.groupby(['categories'])['code_flag'].count().plot(kind='bar')
#添加可视化图形元素
plt.title('各专业方向含有GitHub连接的论文数量',fontsize=16)
x2 = list(range(0,16))
y2= data_with_code.groupby(['categories'])['code_flag'].count()
for x,y in zip(x2,y2):
plt.text(x,y+1,y,ha='center')
统计结果
- 含有GitHub链接的论文共有1000篇;
- 含有GitHub链接的数据样本中,平均每篇论文包含的链接数目不到1个;
- 含有GitHub链接最多的论文,链接数目为4个;
- 含有GitHub链接最多论文类别为cs(计算机专业);
标签:数据分析,code,匹配,论文,页数,plt,学术前沿,data 来源: https://blog.csdn.net/weixin_37700945/article/details/112847809