阿里云天池学习赛零基础入门数据分析-学术前沿趋势分析
前言
本博客主要记录零基础入门数据分析-学术前沿趋势分析的自己的一些理解,主要是解题思路以及代码的解释。大赛地址:零基础入门数据分析-学术前沿趋势分析
一、赛题描述及数据说明
1:数据集的格式如下:
id:arXiv ID,可用于访问论文;
submitter:论文提交者;
authors:论文作者;
title:论文标题;
comments:论文页数和图表等其他信息;
journal-ref:论文发表的期刊的信息;
doi:数字对象标识符,https://www.doi.org;
report-no:报告编号;
categories:论文在 arXiv 系统的所属类别或标签;
license:文章的许可证;
abstract:论文摘要;
versions:论文版本;
authors_parsed:作者的信息。
2:数据集格式举例:
“root”:{
“id”:string"0704.0001"
“submitter”:string"Pavel Nadolsky"
“authors”:string"C. Bal’azs, E. L. Berger, P. M. Nadolsky, C.-P. Yuan"
“title”:string"Calculation of prompt diphoton production cross sections at Tevatron and LHC energies"
“comments”:string"37 pages, 15 figures; published version"
“journal-ref”:string"Phys.Rev.D76:013009,2007"
“doi”:string"10.1103/PhysRevD.76.013009"
“report-no”:string"ANL-HEP-PR-07-12"
“categories”:string"hep-ph"
“license”:NULL
“abstract”:string" A fully differential calculation in perturbative quantum chromodynamics is presented for the production of massive photon pairs at hadron colliders. All next-to-leading order perturbative contributions from quark-antiquark, gluon-(anti)quark, and gluon-gluon subprocesses are included, as well as all-orders resummation of initial-state gluon radiation valid at next-to-next-to leading logarithmic accuracy. The region of phase space is specified in which the calculation is most reliable. Good agreement is demonstrated with data from the Fermilab Tevatron, and predictions are made for more detailed tests with CDF and DO data. Predictions are shown for distributions of diphoton pairs produced at the energy of the Large Hadron Collider (LHC). Distributions of the diphoton pairs from the decay of a Higgs boson are contrasted with those produced from QCD processes at the LHC, showing that enhanced sensitivity to the signal can be obtained with judicious selection of events."
“versions”:[
0:{
“version”:string"v1"
“created”:string"Mon, 2 Apr 2007 19:18:42 GMT"
}
1:{
“version”:string"v2"
“created”:string"Tue, 24 Jul 2007 20:10:27 GMT"
}]
“update_date”:string"2008-11-26"
“authors_parsed”:[
0:[
0:string"Balázs"
1:string"C."
2:string""]
1:[
0:string"Berger"
1:string"E. L."
2:string""]
2:[
0:string"Nadolsky"
1:string"P. M."
2:string""]
3:[
0:string"Yuan"
1:string"C. -P."
2:string""]]
}
二、task1论文数量统计(数据统计任务):统计2019年全年,计算机各个方向论文数量;
1.题目意思解读及整体思路分析
在读取数据集后,有2个思路,先截取2019年发表的论文(通过"update_date"字段),再从中选取论文类别是计算机方向的即可。或是先找出计算机方向的论文,再截取2019年发表的论文。
2.各节代码展示与讲解
2.1:先读取数据集:
def readArxivFile(path, columns = ['id','submitter','authors','title','comments','journal-ref','doi','report-no','categories', 'license', 'abstract', 'versions',
'update_date', 'authors_parsed'] , count = None):
# 读取文件的函数,path:文件路径,columns:需要选择的列,count:读取行数
data = []
with open(path,'r') as f:
for idx, line in enumerate(f):
if idx == count:
break
d = json.loads(line)#把每条数据(json格式) --> 转换成python对象,这里是转换成字典类型
d = {col: d[col] for col in columns}#更改d,只用获取原数据集中的一部分,即columns的部分
data.append(d)
data = pd.DataFrame(data)#将字典类型转换成DataFrame类型
return data
2.1.1: json.load(): 把json格式数据 -> python对象(这里转换成了字典类型),看下图,上面是json格式数据,下面是python的字典类型。
2.1.2: d = {col: d[col] for col in columns} 这里字典类型的索引是col,也就是columns中的每一个,其对应的键值是d[col],从而构成新年的内容,即只选取原数据中的一部分键值对。
2.2:从数据集中截取2019年发表的文章(利用"update_date"字段)
#对2019年以后的paper进行分析,时间处理,数据集中的格式如下:"update_date":string"2008-11-26"
data["year"] = pd.to_datetime(data["update_date"]).dt.year #将update_time从列如2019-09-21的str格式变为datatime格式并提取year
del data["update_date"]
data = data[data["year"] >= 2019 ]
#data.groupby(['categories','year']) #以 categories 进行排序,如果同一个categories 相同则使用 year 特征进行排序
data.reset_index(drop=True,inplace=True)#重新编号
print(data)
2.3:获取计算机方向的论文
2.3.1: 获取计算机方向的论文,那么首先就要知道计算机方向论文的各个种类,比如cs,cv等等,这里本文采取的方式是直接去arXiv网站上去找计算机方向的各个分类,这样保证不会出现纰漏,获取后所有分类后,再用表合并的方式即可完成任务。
2.3.2: 采用request,和beautifulSoup爬取网页(这块不熟悉的请访问博客request库爬虫学习)以及BeautifulSoup库爬虫学习。这里需要分析下标签,方法BeautifulSoup库爬虫学习有讲过,这里说一下,在查看网页源代码的时候,h2是一个大的分类,如:Computer Science,h4标签是这种Computer Science下的一级分类种类:cs.AI(Artificial Intelligence),h3标签是唯独Physics类(该分类很特别,拥有多级分类)下的一级分类,eg:Astrophysics(astro-ph), p标签是对应种类的详细说明:cs.AI(Artificial Intelligence)对应的就是:
Covers all areas of AI except V
#request爬取网页
def getHtmlText(url):
#爬取网页
try:
r = requests.get(url,timeout=30)
r.raise_for_status()
#r.encoding = r.apparent_encoding
return r.text
except:
return "产生异常"
#上面已经获取所有2019年发表的文章,接下来爬取所有的类别
website_html = getHtmlText('https://arxiv.org/category_taxonomy')
soup = BeautifulSoup(website_html,"html.parser")
root = soup.find('div',{'id':'category_taxonomy_list'})#找到网页中类别的相应位置,通过查看网页源代码去找对应的标签
tags = root.find_all(["h2","h3","h4","p"],recursive=True)#取得所有分类的标签
2.3.3: 用正则表达式提取相应信息(请点击博客正则表达式学习)
具体解释请看代码中的注释,就能懂了。
找到的分类结果呈现:
特殊的一类Physics
#初始化str 和 list 变量
level_1_name = ""
level_2_name = ""
level_2_code = ""
level_1_names = [] #一级分类的名称,如:Computer Science,Economics等
# 二级分类的名称,如:只有有些特别的类才有二级分类,这里只有Physics才有:Physics下的Astrophysics(astro-ph),CONDENSEDMATTER(COND-MAT)
level_2_codes = [] ##也是Physics分类下独有的二级分类,Astrophysics(astro-ph)中的astro-ph
level_2_names = [] #Physics分类下独有的二级分类,Astrophysics(astro-ph)中的 Astrophysics
#最后一级的分类,
level_3_codes = [] #cs.AI(Artificial Intelligence)中的 cs.AI
level_3_names = [] #最后一级分类,cs.AI(Artificial Intelligence)中的 Artificial Intelligence
level_3_notes = [] #最后一级分类的详细描述
#进行
for t in tags:
if t.name == "h2":
#h2是一个大的分类,如:Computer Science
level_1_name = t.text
level_2_code = t.text
level_2_name = t.text
elif t.name == "h3":
#h3是唯独Physics类下的一级分类,eg:Astrophysics(astro-ph)
raw = t.text
level_2_code = re.sub(r"(.*)\((.*)\)",r"\2",raw)#(.*)匹配任意个字这个括号是分组标记,\( 左括号,\)右括号。用2来代替
level_2_name = re.sub(r"(.*)\((.*)\)",r"\1",raw)
elif t.name == "h4":
#h4是这种Computer Science下的一级分类种类:cs.AI(Artificial Intelligence)
raw = t.text
level_3_code = re.sub(r"(.*) \((.*)\)",r"\1",raw)
level_3_name = re.sub(r"(.*) \((.*)\)",r"\2",raw)
elif t.name == "p":
#p标签是对应种类的详细说明:cs.AI(Artificial Intelligence)对应的就是:<p>Covers all areas of AI except Vision, Robotics, Machine Learning, Multiagent Systems, and Computation and Language (Natural Language Processing), which have separate subject areas. In particular, includes Expert Systems, Theorem Proving (although this may overlap with Logic in Computer Science), Knowledge Representation, Planning, and Uncertainty in AI. Roughly includes material in ACM Subject Classes I.2.0, I.2.1, I.2.3, I.2.4, I.2.8, and I.2.11.</p>
notes = t.text
level_1_names.append(level_1_name) #一级分类的名称,如:Computer Science,Economics等
level_2_names.append(level_2_name) #二级分类的名称,如:只有有些特别的类才有二级分类,这里只有Physics才有:Physics下的Astrophysics(astro-ph),CONDENSEDMATTER(COND-MAT)
level_2_codes.append(level_2_code)
level_3_names.append(level_3_name) #每个分类的最底层的分类,如Computer Science下的,cs.AI(Artificial Intelligence), Physics类下Astrophysics(astro-ph)下的 astro-ph.CO
level_3_codes.append(level_3_code)
level_3_notes.append(notes)
#生成DataFrame的格式数据
df_taxonomy = pd.DataFrame({
'group_name' : level_1_names, #一级分类,Computer Science,
'archive_name': level_2_names,#Physics分类下独有的二级分类,Astrophysics(astro-ph)中的 Astrophysics
'archive_id' : level_2_codes,#也是Physics分类下独有的二级分类,Astrophysics(astro-ph)中的astro-ph
'category_name' : level_3_names,#最后一级分类,cs.AI(Artificial Intelligence)中的 Artificial Intelligence
'categories' : level_3_codes, #cs.AI(Artificial Intelligence)中的 cs.AI
"category_description" : level_3_notes#最后一级分类的详细描述
})
2.4:获取论文种类后,与之前获得2019年的数据进行合并,并进行可视化展示
2.4.1: 利用两个dataframe中的共同属性’categories’合并,就像两张数据库表合并一样
_df = data.merge(df_taxonomy,on="categories",how="left").drop_duplicates(["id","group_name"]).groupby("group_name").agg({"id":"count"}).sort_values(by="id",ascending=False).reset_index()
#drop_duplicates(subset=['A','B'],keep='first',inplace=True)去除某几列重复的行数据,这里影响不大
#agg()函数:可以对特定的列使用内聚函数(max,min,mean,count等函数)来进行操作,这里把键值对:id作为索引加入进去,并将其累加和(个数)作为其value
print(_df)#所有大类的paper数量分布
2.4.2: pandas可视化
#pandas可视化
fig = plt.figure(figsize=(15, 12))
explode = (0, 0, 0, 0.2, 0.3, 0.3, 0.2, 0.1)
plt.pie(_df["id"], labels=_df["group_name"], autopct='%1.2f%%', startangle=160)
plt.tight_layout()
plt.show()
3.完整代码展示
import seaborn as sns #用于画图
from bs4 import BeautifulSoup
import re
import requests
import json #读取Json格式的数据
import pandas as pd #数据处理,数据分析
import matplotlib.pyplot as plt
def readArxivFile(path, columns = ['id','submitter','authors','title','comments','journal-ref','doi','report-no','categories', 'license', 'abstract', 'versions',
'update_date', 'authors_parsed'] , count = None):
# 读取文件的函数,path:文件路径,columns:需要选择的列,count:读取行数
data = []
with open(path,'r') as f:
for idx, line in enumerate(f):
if idx == count:
break
d = json.loads(line)#把每条数据(json格式) --> 转换成python对象,这里是转换成字典类型
d = {col: d[col] for col in columns}#更改d,只用获取元数据集中的一部分,即columns的部分
data.append(d)
data = pd.DataFrame(data)#将字典类型转换成DataFrame类型
return data
def getHtmlText(url):
#爬取网页
try:
r = requests.get(url,timeout=30)
r.raise_for_status()
#r.encoding = r.apparent_encoding
return r.text
except:
return "产生异常"
if __name__ == "__main__":
data = readArxivFile('arxiv-metadata-oai-2019.json',['id', 'categories', 'update_date'])
#对2019年以后的paper进行分析,时间处理,数据集中的格式如下:"update_date":string"2008-11-26"
data["year"] = pd.to_datetime(data["update_date"]).dt.year #将update_time从列如2019-09-21的str格式变为datatime格式并提取year
del data["update_date"]
data = data[data["year"] >= 2019 ]
#data.groupby(['categories','year']) #以 categories 进行排序,如果同一个categories 相同则使用 year 特征进行排序
data.reset_index(drop=True,inplace=True)#重新编号
print(data)
#上面已经获取所有2019年发表的文章,接下来爬取所有的类别
website_html = getHtmlText('https://arxiv.org/category_taxonomy')
soup = BeautifulSoup(website_html,"html.parser")
root = soup.find('div',{'id':'category_taxonomy_list'})#找到网页中类别的相应位置,通过查看网页源代码去找对应的标签
tags = root.find_all(["h2","h3","h4","p"],recursive=True)#取得所有分类的标签
#初始化str 和 list 变量
level_1_name = ""
level_2_name = ""
level_2_code = ""
level_1_names = [] #一级分类的名称,如:Computer Science,Economics等
# 二级分类的名称,如:只有有些特别的类才有二级分类,这里只有Physics才有:Physics下的Astrophysics(astro-ph),CONDENSEDMATTER(COND-MAT)
level_2_codes = [] ##也是Physics分类下独有的二级分类,Astrophysics(astro-ph)中的astro-ph
level_2_names = [] #Physics分类下独有的二级分类,Astrophysics(astro-ph)中的 Astrophysics
#最后一级的分类,
level_3_codes = [] #cs.AI(Artificial Intelligence)中的 cs.AI
level_3_names = [] #最后一级分类,cs.AI(Artificial Intelligence)中的 Artificial Intelligence
level_3_notes = [] #最后一级分类的详细描述
#进行
for t in tags:
if t.name == "h2":
#h2是一个大的分类,如:Computer Science
level_1_name = t.text
level_2_code = t.text
level_2_name = t.text
elif t.name == "h3":
#h3是唯独Physics类下的一级分类,eg:Astrophysics(astro-ph)
raw = t.text
level_2_code = re.sub(r"(.*)\((.*)\)",r"\2",raw)#(.*)匹配任意个字这个括号是分组标记,\( 左括号,\)右括号。用2来代替
level_2_name = re.sub(r"(.*)\((.*)\)",r"\1",raw)
elif t.name == "h4":
#h4是这种Computer Science下的一级分类种类:cs.AI(Artificial Intelligence)
raw = t.text
level_3_code = re.sub(r"(.*) \((.*)\)",r"\1",raw)
level_3_name = re.sub(r"(.*) \((.*)\)",r"\2",raw)
elif t.name == "p":
#p标签是对应种类的详细说明:cs.AI(Artificial Intelligence)对应的就是:<p>Covers all areas of AI except Vision, Robotics, Machine Learning, Multiagent Systems, and Computation and Language (Natural Language Processing), which have separate subject areas. In particular, includes Expert Systems, Theorem Proving (although this may overlap with Logic in Computer Science), Knowledge Representation, Planning, and Uncertainty in AI. Roughly includes material in ACM Subject Classes I.2.0, I.2.1, I.2.3, I.2.4, I.2.8, and I.2.11.</p>
notes = t.text
level_1_names.append(level_1_name) #一级分类的名称,如:Computer Science,Economics等
level_2_names.append(level_2_name) #二级分类的名称,如:只有有些特别的类才有二级分类,这里只有Physics才有:Physics下的Astrophysics(astro-ph),CONDENSEDMATTER(COND-MAT)
level_2_codes.append(level_2_code)
level_3_names.append(level_3_name) #每个分类的最底层的分类,如Computer Science下的,cs.AI(Artificial Intelligence), Physics类下Astrophysics(astro-ph)下的 astro-ph.CO
level_3_codes.append(level_3_code)
level_3_notes.append(notes)
#生成DataFrame的格式数据
df_taxonomy = pd.DataFrame({
'group_name' : level_1_names, #一级分类,Computer Science,
'archive_name': level_2_names,#Physics分类下独有的二级分类,Astrophysics(astro-ph)中的 Astrophysics
'archive_id' : level_2_codes,#也是Physics分类下独有的二级分类,Astrophysics(astro-ph)中的astro-ph
'category_name' : level_3_names,#最后一级分类,cs.AI(Artificial Intelligence)中的 Artificial Intelligence
'categories' : level_3_codes, #cs.AI(Artificial Intelligence)中的 cs.AI
"category_description" : level_3_notes#最后一级分类的详细描述
})
#按照group_name分组,在组内使用archive_name进行排序
df_taxonomy.groupby(["group_name","archive_name"])
print(df_taxonomy)
# test = df_taxonomy.set_index('group_name')
# test1 = test.loc['Physics']
# print(test1)#可单独提取出所有的Physics的dataframe查看
# print(test1[["archive_name","archive_id"]])
_df = data.merge(df_taxonomy,on="categories",how="left").drop_duplicates(["id","group_name"]).groupby("group_name").agg({"id":"count"}).sort_values(by="id",ascending=False).reset_index()
#drop_duplicates(subset=['A','B'],keep='first',inplace=True)去除某几列重复的行数据,这里影响不大
#agg()函数:可以对特定的列使用内聚函数(max,min,mean,count等函数)来进行操作,这里把键值对:id作为索引加入进去,并将其累加和(个数)作为其value
print(_df)#所有大类的paper数量分布
#pandas可视化
fig = plt.figure(figsize=(15, 12))
explode = (0, 0, 0, 0.2, 0.3, 0.3, 0.2, 0.1)
plt.pie(_df["id"], labels=_df["group_name"], autopct='%1.2f%%', startangle=160)
plt.tight_layout()
plt.show()
#计算机各个子领域2019年后的paper数量
# group_name = "Computer Science"
# cats = data.merge(df_taxonomy,on = "categories").query("group_name == @group_name")
# print(cats.groupby(["year","category_name"]).count().reset_index().pivot(index="category_name",columns="year",values="id"))
# print(cats.groupby(["year","category_name"]).count())
4.代码中几个需要注意的地方(收获到的点):
1)readArxivFile()函数的编写以及with open()的写法,以及enumerate()函数:装换成带下标的数据,json.loads()
def readArxivFile(path, columns = ['id','submitter','authors','title','comments','journal-ref','doi','report-no','categories', 'license', 'abstract', 'versions',
'update_date', 'authors_parsed'] , count = None):
# 读取文件的函数,path:文件路径,columns:需要选择的列,count:读取行数
data = []
with open(path,'r') as f:
for idx, line in enumerate(f):
if idx == count:
break
d = json.loads(line)#把每条数据(json格式) --> 转换成python对象,这里是转换成字典类型
d = {col: d[col] for col in columns}#更改d,只用获取元数据集中的一部分,即columns的部分
data.append(d)
data = pd.DataFrame(data)#将字典类型转换成DataFrame类型
return data
2)是对论文种类分类的级别理解,其实在网站里就能看出不一样: