2021-01-13

DataWhale Task1/论文数据统计笔记

  • Task说明
  • 任务主题:统计2019年全年计算机方向论文数量;
  • 任务内容:基于Pandas进行数据的读取及统计
  • 任务结果:掌握Pandas的基础操作

一、数据载入
1.1数据集介绍
下载地址:https://www.kaggle.com/Cornell-University/arxiv
数据集的格式如下:
id:arXiv ID,可用于访问论文;
submitter:论文提交者;
authors:论文作者
title:论文标题;
comments:论文页数和图表等其他信息;
journal-ref:论文发表的期刊的信息;
doi:数字对象标识符,https://www.doi.org;
report-no:报告编号;
categories:论文在 arXiv 系统的所属类别或标签;
license:文章的许可证;
abstract:论文摘要;
versions:论文版本;
authors_parsed:作者的信息。
1.2 加载数据

#导入Package
import seaborn as sns
from bs4 import BeautifulSoup
import re
import requests
import json
import pandas as pd
import matplotlib.pyplot as plt
#读取数据
data = []
with open("E:/arxiv-metadata-oai-2019.json",'r')as f:
    for idx,line in enumerate(f):
        if idx >= 100:
            break
        data.append(json.loads(line))
data = pd.DataFrame(data)
data.shape
data

enumerate()函数

python 的内置函数,对于一个可迭代的/可遍历的对象,enumerate将其组成一个索引序列,利用它可以同时获得索引和值,一般用于for循环中得到计数。

语法:

enumerate(sequence,[start=0])

参数:

sequence – 一个序列、迭代器或其他支持迭代对象。
start – 下标起始位置。

返回值:返回enumerate(枚举)对象。
实例:

animals = ['dog','pig','snake','shake']
for i,element in enumerate(animals):
    print(i,element)
...
0 dog
1 pig
2 snake
3 shake

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)
            d = {col : d[col] for col in columns}
            data.append(d)

    data = pd.DataFrame(data)
    return data

data = readArxivFile('arxiv-metadata-oai-snapshot.json', ['id', 'categories', 'update_date'])

在这里插入图片描述
二、数据预处理

data["categories"].describe()
count     170618
unique     15592
top        cs.CV
freq        5559
Name: categories, dtype: object

count:一列数据的元素个数;
unique:一列数据中元素的种类;
top:一列数据中出现频率最高的元素;
freq:一列数据中出现频率最高的元素的个数;

由于部分论文的类别不止一种,所以下面我们判断在本数据集中共出现了多少种独立的数据集。

unique_categories = set([i for l in [x.split(' ') for x in data["categories"]] for i in l])
len(unique_categories)
unique_categories
data ['year']=pd.to_datetime(data["update_date"]).dt.year
del data['update_date']
data = data[data['year'] >= 2019]
data.reset_index(drop=True,inplace=True)
data

# data.groupby(['categories','year']) #以 categories 进行排序,如果同一个categories 相同则使用 year 特征进行排序

在这里插入图片描述
我们的任务要求对于2019年以后的paper进行分析,所以首先对于时间特征进行预处理,从而得到2019年以后的所有种类的论文:

#爬取所有的类别
website_url = requests.get('https://arxiv.org/category_taxonomy',verify=False).text
soup = BeautifulSoup(website_url,'lxml')#爬取数据
root = soup.find('div',{'id':'category_taxonomy_list'})
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

在这里插入图片描述

这里主要说明一下上面代码中的正则操作,这里我们使用re.sub来用于替换字符串中的匹配项
pattern : 正则中的模式字符串。
repl : 替换的字符串,也可为一个函数。
string : 要被查找替换的原始字符串。
count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
flags : 编译时用的匹配模式,数字形式。
其中pattern、repl、string为必选参数
re.sub(pattern, repl, string, count=0, flags=0)
详细了解可以参考:https://www.runoob.com/python3/python3-reg-expressions.html

正则表达式
1、字符类

在这里插入图片描述

2、数量限定符

在这里插入图片描述

3、位置限定符

在这里插入图片描述

实例

import re

phone = "2004-959-559 # 这是一个电话号码"
 
# 删除注释
num = re.sub(r'#.*$', "", phone)
print ("电话号码 : ", num)
 
# 移除非数字的内容
num = re.sub(r'\D', "", phone)
print ("电话号码 : ", num)

电话号码 :  2004-959-559 
电话号码 :  2004959559

三、数据分析及可视化
使用merge函数,以两个dataframe共同的属性 “categories” 进行合并,并以 “group_name” 作为类别进行统计,统计结果放入 “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()
_df

在这里插入图片描述

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()

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值