データ分析の最初のチーム研究ノート-リジー
@Datawhale
タスク1:紙のデータ統計
- 研究トピック:論文数の統計(データ統計タスク)、2019年全体のコンピューターのさまざまな分野の論文数を数えます。
- 学習内容:競争の質問の理解
Pandas
、データの読み取り、データ統計; - 学習成果:学習
Pandas
基盤;
1.1紙のjsonファイルを読む
json:紙のデータはjson形式であるため、それらを読み取り、Pythonの組み込みデータ構造に読み込むには、インポートjsonモジュールが必要です。
json.loads()メソッドは、appendを使用して、読み取った各行をリストオブジェクトに渡すことができます。
データセットが大きすぎるので、ここでは最初の100,000の論文のデータを読み、それらを数えました。具体的なコードは次のとおりです。
#首先导入需要使用的包
import pandas as pd#用于数据处理
#然后我用基本的文件操作读取了前100000个论文,并利用DataFrame的head()方法来显示其中的前五行,代码如下
data=[]
num=0
with open("D:\\arxiv-metadata-oai-snapshot.json",'r')as f:
for line in f:
data.append(json.loads(line))
num+=1
if num >99999:
break
data=pd.DataFrame(data)
data.shape
data.head()
14個の機能番号に対応する合計14個のタグがあることがわかります。
1.2データの前処理
カタログの特性を分析するために、ここではdescribeメソッド()を使用します。これは、一度に複数の要約統計量を生成できる単純な記述メソッドです。
数値データと非数値データの場合、出力が異なります。ここでの型は数値データではありません。コードの特性に応じて型を分析します。
data['categories'].describe()
Countはカウント、uniqueは一意の値、topは最も頻度の高いカテゴリ、freqはこのカテゴリの頻度です。分析の結果、上位100,000のデータのうち、6068番目のカテゴリは1回だけ表示されます。最も頻繁な1つのタイプはastro-ph(天体物理学)です。2019年のデータのみが必要なため、初めてデータを前処理する必要があります。コードは次のとおりです。
#这个操作首先提取出时间这一列,然后将它转化为datatime格式,这是pandas自己内置的一种数据类型
data['year']=pd.to_datetime(data['update_date']).dt.year#只提取其中的年份,此时也新建了一列'year’,
del data["update_date"]
data=data[data'year'>=2019]#删除2019年之前的数据
data.reset_index(drop=True, inplace=True)
data
ここでは、reset_indexを使用せず、reindexのみを使用しているため、両者の違いがわかりました。reindexは列または行を再配置し、reset_indexはインデックスを再配置します。これは、操作を削除すると、データが連続データではなくなる可能性があるためです。 。reset_index操作を使用すると、元のインデックスが新しい列になります。表示したくない場合は、パラメーターdrop = Trueを渡すことができます。このパラメーターはデフォルトでfalseであり、別のパラメーターがインプレースされています。の意味は、1つを再構築するか、元のDataFrameで変更することです。デフォルトでは、インプレースはfalseであり、新しいオブジェクトを作成します。
スクリーニングを通じて、2019年の新しいデータを取得できます。
次に、コンピュータフィールドのデータをフィルタリングし、年、ID、カテゴリを3列のみ保持します
data=data[['id','categories','year']]
1.3クロールペーパーの種類
クローラーはこの点でBeautifulSoupのみを使用しており、通常のルールについてはまだよく知りません-
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
groupby関数:特定のインデックスでグループ化すると、Excelのフィルタリング操作と同様に、さまざまなパラメーターを受け入れることができます。
次に、カテゴリのDateFrameと論文データのDataFrameの間で共通の属性「categories」をマージし、統計のカテゴリとして「group_name」を使用し、統計結果を「id」列に入れて並べ替えます。
私は非常に強力だと感じているので、ここにマージメソッドの使用法を補足するための鍵があります:
マージ関数:マージおよびリンク操作に使用されます:たとえば、pd.merge(df1、df2)、接続するときは、on = 'key'などの指定されたキーを表示するのが最適です。
さらに、パラメーターhowがあり、「inner」、「outer」、「left」、「right」の4種類の値があり、交差、和集合、左テーブル、右テーブルの異なるマージベンチマークを表します。
_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->去重操作
#agg->列上以数值进行聚合
#sort_values->排序操作
サンプルコードの多くのタイプと比較すると、これは同じタイプの紙のほとんどが一緒にクラスター化されているため、タイプが制限されているためだと思います
1.4データ分析と視覚化
matplotlibモジュールは、ここでは主に基本的な視覚化操作に使用されます。コードはおおまかに次のとおりです。
import matplotlib.pyplot as plt#导入画图模块
fig=plt.figure(figsize=(15,12))#以窗口的格式展示,窗口大小为(15,12)
plt.pie(_df['id'],labels=_df['group_name'],autopct='%1.1f',explode=(0,0,0.2))#创建一个饼图
plt.tight_layout()#自动调节参数,使图片填充整个图
plt.show()
ここでは、円グラフを作成する必要があります。pie()関数のパラメーターについて、以下に詳しく説明します。
x :(每一块)的比例,如果sum(x) > 1会使用sum(x)归一化;
labels :(每一块)饼图外侧显示的说明文字;
explode :(每一块)离开中心距离;
startangle :起始绘制角度,默认图是从x轴正方向逆时针画起,如设定=90则从y轴正方向画起;
shadow :在饼图下面画一个阴影。默认值:False,即不画阴影;
labeldistance :label标记的绘制位置,相对于半径的比例,默认值为1.1, 如<1则绘制在饼图内侧;
autopct :控制饼图内百分比设置,可以使用format字符串或者format function
'%1.1f'指小数点前后位数(没有用空格补齐);
pctdistance :类似于labeldistance,指定autopct的位置刻度,默认值为0.6;
radius :控制饼图半径,默认值为1;counterclock :指定指针方向;布尔值,可选参数,默认为:True,即逆时针。将值改为False即可改为顺时针。wedgeprops :字典类型,可选参数,默认值:None。参数字典传递给wedge对象用来画一个饼图。例如:wedgeprops={'linewidth':3}设置wedge线宽为3。
textprops :设置标签(labels)和比例文字的格式;字典类型,可选参数,默认值为:None。传递给text对象的字典参数。
center :浮点类型的列表,可选参数,默认值:(0,0)。图标中心位置。
frame :布尔类型,可选参数,默认值:False。如果是true,绘制带有表的轴框架。
rotatelabels :布尔类型,可选参数,默认为:False。如果为True,旋转每个label到指定的角度。
さて、最後のステップに進みましょう。しかし、2019年以降、物理学の分野の論文数を数えるという目標を変更したいと思います。emerge関数も使用します。ただし、の分野についてあまり詳しくないためです。物理学、私はもはやデータ分析を行いません。
最終的なコードは次のとおりです。
group_name="Physics"
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")
それらのほとんどは高エネルギー物理学と呼ばれているようです、私はhhhについてあまり知りません