Github项目数据统计

Github项目数据统计

​ 由于需要统计Dapp项目的发展历程数据,在查资料时看到了以太坊 Dapp 调研,这份统计只包含了2017年12月20日及之前的数据,而现在已经是2021年了,因此我模仿这个进行了新的统计。

数据获取

经过一系列学习,我终于掌握了GitHub api的基础使用。简单来说,我们可以通过访问api接口进行查询并获取数据。通过关键字dapp进行查询的api是https://api.github.com/search/repositories?q=dapp,用浏览器直接打开这个链接可以看到如下图的内容:

image-20210430103142883

第一行的total_count是所有结果的总数,接下来有30个items,每一个都是对应的项目,点开第一个可以看到其数据格式为:

image-20210430103308097

图中显示的内容并不完整,还有很多信息比如stars数量等都可以直接获取。

但是总共有19930个项目,却只获取到30个,这显然是不够的,想获取更多项目就需要修改api的内容,改成https://api.github.com/search/repositories?q=dapp&page=1&per_page=100,修改后就可以获取到100条项目信息了,这是每页项目数的上限,将api中的page=1改成page=2即可得到新的100条信息,然而由于api限制,通过这样的方法最多可以获取1000条(即page=10),超过1000条后会有报错信息。为了能获取到更多项目,我们需要对访问查询作出限制,使得每次查询结果都不超过1000条,然后将多次查询结果合并起来得到完整结果,例如仅查找创建于2021年1月至2月的项目数,这样就可以得到1000条以内的结果,再逐页访问即可。限制时间的api为:https://api.github.com/search/repositories?q=dapp+created:2021-04-01T00:00:00..2021-05-01&page=1&per_page=100,这个api可以获取创建时间在2021年4月1日至5月1日的所有项目数据,如果要获取其他时间范围,对api中的时间进行修改即可,可以精确到秒;如果时间限制是早于或晚于某个时间点,则写成created:>=2021-04-01T00:00:00,大于等于符号可以改成小于等于或者大于或者小于。如果想限制其他字段,比如更新时间,则把created修改为updated即可。

具体到写python代码时,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from github3 import login, GitHub
import getpass
import re
import requests
import json
import csv

def main():
result = requests.get("https://api.github.com/search/repositories?q=dapp+created:2021-04-01T00:00:00..2021-05-01&page=6&per_page=100")
response_dict = result.json()
repo_dicts = response_dict['items']
print("Toal repositories:", response_dict['total_count'])
print("Repositories returned:", len(repo_dicts))
keys = {'id','full_name','html_url','commits_url','language','description','forks_count','stargazers_count','watchers_count','created_at','pushed_at','updated_at'}
save_dicts = []
for i in repo_dicts:
j = {key: value for key, value in i.items() if key in keys}
save_dicts.append(j)
with open('test.csv', 'a+', newline='',encoding='utf-8') as f:
fieldnames = ['id','full_name','html_url','commits_url','language','description','forks_count','stargazers_count','watchers_count','created_at','pushed_at','updated_at']
writer = csv.DictWriter(f,fieldnames=fieldnames)
#writer.writeheader()
writer.writerows(save_dicts)

if __name__ == "__main__":
main()

这段代码import的一些包其实没有用到,是最初学着写的时候都引入了,之后没删。

代码第9行使用requests.get()获取api的数据,接着使用.json()将它转为字典。这个字典的total_count项就是前面图中显示的项目总数,这里我们没有用到;字典的items项则是我们需要的项目列表,将它单独存到repo_dicts,显然获取的项目列表数并不等于项目总数。

接下来把这次数据处理所需要的字段写到keys中,从repo_dicts中提取这些列的内容存到新列表save_dicts中,再将这些数据保存到csv文件里。这个提取数据并保存的过程应该有更简练的代码写法,我懒得改了就这样吧。

最终得到的csv文件如下图所示:

image-20210430105338111

这个数据总量比api那里的总量要多一些,显然是有重复的,因此要进行去重,我们选择把相同id的条目删了,只保留一个。excel本身就有去重的功能,在python里用pandas也可以,代码如下:

1
2
3
4
5
6
7
8
9
10
import csv
import pandas as pd

def main():
frame=pd.read_csv('test.csv',engine='python')
data = frame.drop_duplicates(subset=['id'], keep='first', inplace=False)
data.to_csv('newtest.csv', encoding='utf8')

if __name__ == "__main__":
main()

这样就得到了一份到目前为止所有和dapp相关的项目表。

数据处理

接下来要对所有数据进行分析统计。我们要做的图表如下:

  1. 每月新Dapp项目数量分布
  2. 项目创建及更新时间分布
  3. 项目语言分布

第3个最简单,我们先看它。

项目语言分布

从csv文件读入数据后,按language列进行数量统计即可,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import csv
import pandas as pd

pd.set_option('display.max_rows',None)
pd.set_option('display.max_columns', None)
pd.set_option('display.width', 1000)
pd.set_option('display.max_colwidth', 1000)

def main():
frame=pd.read_csv('newtest.csv',engine='python')
df1 = frame.language.value_counts()
print(df1)

if __name__ == "__main__":
main()

输出结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
JavaScript           10018
C# 2087
HTML 1019
TypeScript 806
CSS 376
Solidity 336
Vue 335
Java 295
Python 256
Shell 139
Go 133
C++ 120
Dockerfile 72
PHP 65
Kotlin 54
Ruby 52
Swift 49
Dart 37
Rust 34
Objective-C 30
Jupyter Notebook 30
C 25
Makefile 24
WebAssembly 22
TSQL 19
SCSS 17
PowerShell 10
F# 10
TeX 9
Perl 8
Clojure 8
Haskell 7
R 7
Svelte 6
CoffeeScript 6
Scala 6
Nix 5
Visual Basic 5
Visual Basic .NET 5
D 4
Elm 4
Smarty 3
Elixir 3
GLSL 3
ASP 3
HCL 3
PLpgSQL 2
ShaderLab 2
OCaml 2
Logos 2
Blade 2
Roff 2
LiveScript 2
Hack 2
PLSQL 2
Sass 1
ECL 1
GDScript 1
NSIS 1
Stata 1
CMake 1
MATLAB 1
EJS 1
Twig 1
QML 1
XML 1
Batchfile 1
Crystal 1
Apex 1
Emacs Lisp 1
Lua 1
Racket 1
VimL 1
Handlebars 1
4D 1
PureScript 1
Pascal 1
Io 1
Assembly 1
Name: language, dtype: int64

每月新增Dapp项目数量分布

从csv文件读入数据后,访问created_at这一列并截取其前7位,即可得到每个项目的创建年月,统计每个月创建的项目数量即可得到数据结果,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import csv
import pandas as pd

pd.set_option('display.max_rows',None)
pd.set_option('display.max_columns', None)
pd.set_option('display.width', 1000)
pd.set_option('display.max_colwidth', 1000)

def main():
frame=pd.read_csv('newtest.csv',engine='python')
frame['created'] = frame['created_at'].str[0:7]
df1 = frame.created.value_counts()
print(df1)

if __name__ == "__main__":
main()

这份数据内容很多,因此就不列出了。

项目创建及更新时间分布

由于数据很多,因此这里并不逐月统计,对于创建时间,统计每半年的项目数;对于更新时间,统计每一年的项目数,例如创建于2009年10月至2010年4月且最后一次更新于2014年4月至2015年4月的项目有1个,则这一对时间所对应的值就是1。以此类推,可以得到一份完整表格。

我们首先读入csv文件,截取创建和更新的年月数据,并依次分组并统计每组的项目数,这样就可以得到每组年月对所对应的项目数,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import csv
import pandas as pd

pd.set_option('display.max_rows',None)
pd.set_option('display.max_columns', None)
pd.set_option('display.width', 1000)
pd.set_option('display.max_colwidth', 1000)

def main():
frame=pd.read_csv('newtest.csv',engine='python')
frame['created'] = frame['created_at'].str[0:7]
frame['updated'] = frame['updated_at'].str[0:7]
group = frame.groupby(['created','updated'])
dict_tmp = dict(group.size())
print(dict_tmp)

if __name__ == "__main__":
main()

得到的结果是... ('2021-03', '2021-03'): 473, ('2021-03', '2021-04'): 151,...这样的格式,将这些放到excel里并进行分列、去除无效数据等处理,最终可以得到如下图所示的表格:

image-20210430122233349

接下来筛选出created列中2014-11~2015-04之间的数据,将筛选后的updated和num这两列复制到新区域(比如sheet4),按升序排列,如下图,选中2015-04之前的数据,就可以在右下角看到这个时间段内的项目数总和。

image-20210430122713555

用类似的方法进行多次筛选、排序、求和,最终可以得到如下数据表:

image-20210430124738534

行表示创建时间,列表示更新时间。

图像生成

使用Echarts生成图表,因为没学过前端,所以就直接用了以太坊 Dapp 调研给出的js代码,链接为 Github

所有数据是直接在web.js中写好的,并不是从其他文件读取,且文件开头的var scatter_origin_data其实可以删了。此外,这份文件中的个人和组织项目散点图我并不需要,因此也直接删了。

接下来将web.js中的数据修改成前面统计好的数据,打开web.html就可以看到图表了。

由于hexo博客也可以显示echarts,因此我就把图表放这里了。

fe0b04c74a9bae3058a8c53ba973f4e

热力图不知道为什么始终没法在这里显示,所以就放个截图了……

  • Copyrights © 2020-2024 Kun Li

请我喝杯咖啡吧~

支付宝
微信