任务说明
-任务说明
- 任务主题:论文数量统计,即统计2019年全年Statistics各个方向论文数量;
- 任务内容:赛题的理解、使用 Pandas 读取数据并进行统计;
- 任务成果:学习 Pandas 的基础操作;
- 可参考的学习资料:开源组织Datawhale joyful-pandas项目https://github.com/datawhalechina/joyful-pandas
数据集介绍
数据集来源:https://www.kaggle.com/Cornell-University/arxiv
arxiv论文类别介绍
https://arxiv.org/category_taxonomy
部分介绍如下
具体代码实现
导入package并读取原始数据
// An highlighted block
# 导入所需的package
import seaborn as sns #用于画图
from bs4 import BeautifulSoup #用于爬取arxiv的数据
import re #用于正则表达式,匹配字符串的模式
import requests #用于网络连接,发送网络请求,使用域名获取对应信息
import json #读取数据,我们的数据为json格式的
import pandas as pd #数据处理,数据分析
import matplotlib.pyplot as plt #画图工具
// An highlighted block
# 读入数据
data = []
#使用with语句优势:1.自动关闭文件句柄;2.自动显示(处理)文件读取数据异常
with open("arxiv-metadata-oai-2019.json", 'r') as f:
for idx, line in enumerate(f):
# 读取前100行,如果读取所有数据需要8G内存
if idx >= 100:
break
data.append(json.loads(line))
data = pd.DataFrame(data) #将list变为dataframe格式,方便使用pandas进行分析
data.shape #显示数据大小
data.head(5) #显示数据的前五行
数据预处理
首先我们先来粗略统计论文的种类信息:
- count:一列数据的元素个数;
- unique:一列数据中元素的种类;
- top:一列数据中出现频率最高的元素;
- freq:一列数据中出现频率最高的元素的个数;
// An highlighted block
data["categories"].describe()
由于部分论文的类别不止一种,所以下面我们判断在本数据集中共出现了多少种独立的数据集。
// An highlighted block
unique_categories = set([i for l in [x.split(' ') for x in data["categories"]] for i in l])
len(unique_categories)
unique_categories
我们的任务要求对于2019年以后的paper进行分析,所以首先对于时间特征进行预处理,从而得到2019年以后的所有种类的论文:
// An highlighted block
data["year"] = pd.to_datetime(data["update_date"]).dt.year #将update_date从例如2019-02-20的str变为datetime格式,并提取处year
del data["update_date"] #删除 update_date特征,其使命已完成
data = data[data["year"] >= 2019] #找出 year 中2019年以后的数据,并将其他数据删除
# data.groupby(['categories','year']) #以 categories 进行排序,如果同一个categories 相同则使用 year 特征进行排序
data.reset_index(drop=True, inplace=True) #重新编号
data #查看结果
这里我们就已经得到了所有2019年以后的论文,下面我们挑选出计算机领域内的所有文章:
// An highlighted block
var foo = 'bar';
#爬取所有的类别
website_url = requests.get('https://arxiv.org/category_taxonomy').text #获取网页的文本数据
soup = BeautifulSoup(website_url,'lxml') #爬取数据,这里使用lxml的解析器,加速
root = soup.find('div',{'id':'category_taxonomy_list'}) #找出 BeautifulSoup 对应的标签入口
tags = root.find_all(["h2","h3","h4","p"], recursive=True) #读取 tags
#初始化 str 和 list 变量
level_1_name = ""
level_2_name = ""
level_2_code = ""
level_1_names = []
level_2_codes = []
level_2_names = []
level_3_codes = []
level_3_names = []
level_3_notes = []
#进行
for t in tags:
if t.name == "h2":
level_1_name = t.text
level_2_code = t.text
level_2_name = t.text
elif t.name == "h3":
raw = t.text
level_2_code = re.sub(r"(.*)\((.*)\)",r"\2",raw) #正则表达式:模式字符串:(.*)\((.*)\);被替换字符串"\2";被处理字符串:raw
level_2_name = re.sub(r"(.*)\((.*)\)",r"\1",raw)
elif t.name == "h4":
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":
notes = t.text
level_1_names.append(level_1_name)
level_2_names.append(level_2_name)
level_2_codes.append(level_2_code)
level_3_names.append(level_3_name)
level_3_codes.append(level_3_code)
level_3_notes.append(notes)
#根据以上信息生成dataframe格式的数据
df_taxonomy = pd.DataFrame({
'group_name' : level_1_names,
'archive_name' : level_2_names,
'archive_id' : level_2_codes,
'category_name' : level_3_names,
'categories' : level_3_codes,
'category_description': level_3_notes
})
#按照 "group_name" 进行分组,在组内使用 "archive_name" 进行排序
df_taxonomy.groupby(["group_name","archive_name"])
df_taxonomy
数据分析及可视化
接下来我们首先看一下所有大类的paper数量分布:
我们使用merge函数,以两个dataframe共同的属性 “categories” 进行合并,并以 “group_name” 作为类别进行统计,统计结果放入 “id” 列中并排序。
// An highlighted block
_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()
_df
group_name | id |
---|---|
Physics | 38379 |
Mathematics | 24495 |
Computer Science | 18087 |
Statistics | 1802 |
Electrical Engineering and Systems Science | 1371 |
Quantitative Biology | 886 |
Quantitative Finance | 352 |
Economics | 173 |
下面我们使用饼图进行上图结果的可视化:
// An highlighted block
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, explode=explode)
plt.tight_layout()
plt.show()
下面统计在Statistics各个子领域2019年后的paper数量,我们同样使用 merge 函数,对于两个dataframe 共同的特征 categories 进行合并并且进行查询。然后我们再对于数据进行统计和排序从而得到以下的结果
// An highlighted block
group_name="Statistics"
cats = data.merge(df_taxonomy, on="categories").query("group_name == @group_name")
cats.groupby(["year","category_name"]).count().reset_index().pivot(index="category_name", columns="year",values="id")
category_name | 2019 |
---|---|
Applications | 558 |
Computation | 163 |
Machine Learning | 66 |
Methodology | 973 |
Other Statistics | 42 |
我们可以从结果看出,Methodology类是Statistics中paper数量最多的子类,遥遥领先于其他的Statistics子类。