数据分析学习——学术前沿趋势分析 任务3(论文代码统计)

任务3: 论文代码统计

3.1 任务说明

  • 任务主题:论文代码统计,统计所有论文出现代码的相关统计;
  • 任务内容:使用正则表达式统计代码连接、页数和图表数据;
  • 任务成果:学习正则表达式统计;

3.2 数据处理步骤

在原始arxiv数据集中作者经常会在论文的commentsabstract字段中给出具体的代码链接,所以我们需要从这些字段里面找出代码的连接。

  • 确定数据出现的位置;
  • 使用正则表达式完成匹配;
  • 完成相关的统计;

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(计算机专业);

猜你喜欢

转载自blog.csdn.net/weixin_37700945/article/details/112847809
今日推荐