Python 中最流行的十個標準庫

Python實戰社羣

Java實戰社羣

長按識別下方二維碼,按需求添加

掃碼關注添加客服

進Python社羣▲

掃碼關注添加客服

進Java社羣

作者 | Arghavan Moradi

譯者 | Sambodhi

策劃 | 劉燕

來源公衆號丨AI前線(ID:ai-front)

Python 以其有用的庫和包而著稱,即使沒有軟件工程背景的人也能編程。本文基於 GitHub 倉庫的示例數據集,探索流行的 Python 標準庫。

Python 是當今人工智能和機器學習領域最流行的編程語言之一。Python 以其有用的庫和包而著稱,即使沒有軟件工程背景的人也能編程。

Python 擁有一組與 Python 語言一起分發的標準庫,如 DateTime、math 或 Random。本文的目標是在 GitHub 的 Python 倉庫中找到 10 個最有用的標準庫。爲實現我們的目標,我們研究了 GitHub 中不同的 Python 倉庫,並收集了它們的舊庫來回答這個問題。

爲了開始我們的研究,首先,我們收集了 GitHub 中 5 個著名的 Python 資源庫在過去一年的提交情況。然後,我們對這些倉庫中的 Python 源文件進行解析,並收集其提交中使用的庫。最後,我們將這些 GitHub 倉庫提交中使用的 10 個最流行的 Python 標準庫進行可視化。

如何收集數據?

有不同的方法可以訪問 GitHub 倉庫中的數據,例如 GitHub torrent、Git API 調用或 Google big query。但是,在本文中,我們想要嘗試一個新的非常有用的 Python 包,名爲 Pydriller,它可以收集我們需要的數據。Pydriller 速度快,使用方便。我是在攻讀博士學位的時候熟悉了這個有趣的包。你可以在 這裏 查看 Pydriller 的文檔。要從 Pydriller 開始,首先,我們安裝包:

pip install pydriller

每次提交時,GitHub 中的一個或多個源文件都可以被修改。在 GitHub 這樣的版本控制系統中,每一次提交都有一個文件,名爲“diff”。它通過提交特定的提交來存儲在源文件中應用的更改。在 GitHub 倉庫的提交中查找庫的方法之一是在“diff”文件中搜索正則表達式。

但在本文中,我們想嘗試一些不同的方法。我們比較兩個不同版本的源文件“提交之前”和“提交之後”應用提交,然後收集這兩個文件在庫名中的差異。

通過這種方法,我們就可以發現庫在不同提交中的使用頻率。好消息是,Pydriller 允許我們在應用提交之前和應用提交之後訪問源文件的版本。下面是收集數據所需的代碼:

#import libraries
import pydriller as pyd
from datetime import datetime
#period to collect data
dt1 = datetime(2019, 11, 1)
dt2 = datetime(2020, 11, 1)
#path of 5 Python repositories
path = ["https://github.com/django/django.git","https://github.com/pandas-dev/pandas.git",
        "https://github.com/numpy/numpy","https://github.com/home-assistant/home-assistant.git",
        "https://github.com/donnemartin/system-design-primer.git"]
#collecting a version of a source file before and after applying a commit
tf_source = pd.DataFrame(columns=['commit_ID', 'before_Commit', 'after_Commit'])
for commit in pyd.RepositoryMining(path_to_repo=path, since=dt1, to=dt2).traverse_commits():
    for modified_file in commit.modifications:
        if modified_file.filename.endswith(".py"):
            tf_source = tf_source.append({'commit_ID': commit.hash,'before_Commit': modified_file.source_code_before,
                                          'after_Commit': modified_file.source_code}, ignore_index=True)

用 Pydriller 在 GitHub 中收集 5 個著名的 Python 庫。

我們在 GitHub 上收集了 5 個大的 Python 項目在去年的提交情況,其中有 Django、Pandas、NumPy、Homeassistant、system-design-primer。“RepositoryMining”是 Pydriller 的主要 API 調用之一。

我們可以通過 RepositoryMining 中的兩個參數來定義一個時間段來收集不同倉庫中的提交:sinceto。另外,我們考慮所有名稱以“.py”結尾的源文件的提交,因爲這些資源庫中也有其他編程語言的源文件,但我們關注的是 Python 庫。

我們收集了三個特徵:commit.hashsource_code_beforesource_code。Pydriller 中的commit.hash返回提交的idsource_code_before是應用提交前的源文件版本,source_code則顯示提交後的源文件內容。下面是我們收集的數據頭:

tf_source.head()

到目前爲止,我們已經收集了開始旅程所需的數據。在下一節中,我們將學習如何探索這些源文件中的庫。

如何解析 Python 源代碼

提取源代碼中信息的方法之一是將它們轉換成抽象語法樹(Abstract Syntax Tree,AST)。然後,我們就可以遍歷這棵樹,並收集目標節點。

但最重要的一點是,我們只想收集 Python 標準庫,而不是所有在倉庫中使用的包,比如本地定義的庫,它們只有在倉庫中才有意義。Python 標準庫是和 Python 語言一起發佈的。

因此,爲了將標準包和其他包分開,我們需要拉取 Python 中所有有效的標準庫。然後,我們可以寫一個函數來收集源代碼中的庫名。

我們可以將本節分爲兩步:收集 Python 中所有可用的標準庫的列表、構建基於抽象語法書的函數來收集庫名。

1. 收集 Python 中所有可用的標準庫的列表

在 Python 的網站 上,有一張 Python 中所有標準庫的列表,並附有簡短說明。這個頁面將所有的 Python 標準庫按字母名稱排序,幫助我們對 Python 中所有的標準庫進行拉取。我把所有 Python 標準庫的列表放在 這裏,以 .csv 的格式。

2. 構建基於抽象語法書的函數來收集庫名

既然我們有了所有標準 Python 庫的列表,我們就需要從 Python GitHub 倉庫中收集我們示例數據集中的庫名稱。正如我們提到的,其中一種方法是遍歷抽象語法樹。

在本文中,我們的目標節點是importimportfrom。我們希望有一個函數遍歷解析樹,找到目標節點,並返回庫的名稱。下面是這樣做的類。

#import libraries
import ast
import tokenize
#A class to walk trough AST and collect libraries name
class FuncParser(ast.NodeVisitor):
def visit_Import(self, node):
tempImpo = node.names
if(tempImpo != None):
listImpo = tempImpo[0]
Impo = listImpo.name
if (Impo in api_name):
file_contents.append(Impo)
ast.NodeVisitor.generic_visit(self, node)
else:
ast.NodeVisitor.generic_visit(self, node)
def visit_ImportFrom(self, node):
module=node.module
if(module in api_name):
file_contents.append(module)
else:
ast.NodeVisitor.generic_visit(self, node)
def generic_visit(self, node):
ast.NodeVisitor.generic_visit(self, node)

在 Python 代碼中收集庫名的類。

爲了更好地理解這個類的工作原理,下面是一段簡單的代碼。這段示例代碼只有兩行,分別導入了兩個不同的庫,其中一個是 python 標準庫:tokenize,另一個是本地庫:assistant

import tokenize as tz
import assistant as ass

下面是這個示例代碼的解析樹的轉儲。可以發現,我們需要收集的是作爲alias類中的name參數。

此外,我們還需要檢查庫的名稱是否在我們從 Python 原始網站收集的所有標準庫的列表中。我們將 .csv 文件保存在名爲api_name的列表中。

如果我們在這個示例代碼上應用這個類FuncParser,它將只返回tokenize,因爲另一個庫assistant在 Python 標準庫列表中不可用。

Module(body=[Import(names=[alias(name='tokenize', asname='tz')]), Import(names=[alias(name='assistant', asname='ass')])])

Python 倉庫中基於 GitHub 提交的 10 個最流行標準庫是什麼

到目前爲止,我們收集了 GitHub 中 5 個著名的 Python 倉庫的示例數據集,並構建了一個類來收集 Python 代碼中的庫名。

現在,我們需要將這個函數應用到 GitHub 的示例數據中,並找出這些倉庫的提交中使用的前 10 個庫。正如我們前面所討論的,我們將提交提交之前的源文件的抽象語法樹和提交提交之後的同一源文件的抽象語法樹進行比較,然後我們收集不同的庫節點。

然後我們收集不同的庫節點。首先,我會給大家展示一個步驟性的示例,告訴大家如何比較這兩個抽象語法樹,最後,我把所有的代碼放在一起,以循環遍歷整個數據集,並計算每個庫的出現次數。

1. 提交提交之前收集庫名列表

我們將示例數據集存儲在tf_source中,我選擇這個數據集的第一行來解釋整個過程。tf_source'Commit_before' 返回示例數據集中第一次提交前的代碼內容。

然後,我們應用FuncParser()來收集這個源文件中的所有庫名,並在file_contents列表中返回結果。我們創建一個名爲tokens_before的數據框架,並存儲這個列表。

text_before=str(tf_source[‘Commit_before’](0))

bf_obj = FuncParser()
bf_tree = ast.parse(text_before)
file_contents = []
bf_obj.visit(bf_tree)
dtobj_before = pd.DataFrame(file_contents, columns=[‘token’])
tokens_before =pd.DataFrame(dtobj_before[‘token’].value_counts())

2. 提交提交之後收集庫名列表

我們重複與上面的步驟相同的過程,但這次是在提交提交之後對源文件的內容進行的,tf_source‘Commit_after’。

另外,我們將結果存儲在一個名爲tokens_after的數據幀中。

text_after=str(tf_source[‘Commit_after’](0))

 aft_obj = FuncParser()
aft_tree = ast.parse(text_after)
file_contents = []
aft_obj.visit(aft_tree)
dtobj_after = pd.DataFrame(file_contents, columns=[‘token’])
tokens_after =pd.DataFrame(dtobj_after[‘token’].value_counts())

3. 找出這兩個列表之間的差異

在這一步中,我們從tokens_after中減去tokens_before以計算它們的差異。

diff = tokens_after.subtract(tokens_before)
diff_token = diff[(diff.select_dtypes(include=[‘number’]) != 0).any(1)]
diff_token=diff_token.fillna(0)
diff_token= diff_token.abs()
diff_token = diff_token.reset_index()

4. 計算庫的數量

最後,我們統計每個庫在diff_token數據幀中出現的次數。爲此,我們創建一個名爲py_lib的字典,並統計庫的出現次數。

py_lib={}
j=0
for j in range(0,len(diff_token)):
word = diff_token['index'](j).lower()
if word in py_lib:
py_lib[word]+=diff_token['token'](j)
else:
py_lib[word]=1
j+=

爲了將上述步驟應用於我們在前面收集的整個示例數據中,我在步驟的開頭添加了一個循環。下面是代碼:

i=0
error=0
py_lib={}
for row in tf_source.iterrows():

#parsing the source file before applying commit i
if tf_source['Commit_before'](i) is not None:
try:
text_before=str(tf_source['Commit_before'](i))


bf_obj = FuncParser()
bf_tree = ast.parse(text_before)
file_contents = []
bf_obj.visit(bf_tree)
dtobj_before = pd.DataFrame(file_contents, columns=['token'])
tokens_before =pd.DataFrame(dtobj_before['token'].value_counts())

except:
error +=1
else:
file_contents = []
dtobj_before = pd.DataFrame(file_contents, columns=['token'])
tokens_before =pd.DataFrame(dtobj_before['token'].value_counts())

#parsing the source file after applying commit i
if tf_source['Commit_after'](i) is not None:
try:
text_after=str(tf_source['Commit_after'](i))


aft_obj = FuncParser()
aft_tree = ast.parse(text_after)
file_contents = []
aft_obj.visit(aft_tree)
dtobj_after = pd.DataFrame(file_contents, columns=['token'])
tokens_after =pd.DataFrame(dtobj_after['token'].value_counts())

except:
error +=1
else:
file_contents = []
dtobj_after = pd.DataFrame(file_contents, columns=['token'])
tokens_after =pd.DataFrame(dtobj_after['token'].value_counts())


#calculating the differences between two list tokens_before and tokens_after
diff = tokens_after.subtract(tokens_before)
diff_token = diff[(diff.select_dtypes(include=['number']) != 0).any(1)]
diff_token=diff_token.fillna(0)
diff_token= diff_token.abs()
diff_token = diff_token.reset_index()

# counting the numer of each libraries which are added or removed by commit i
j=0
for j in range(0,len(diff_token)):
word = diff_token['index'](j).lower()
if word in py_lib:
py_lib[word]+=diff_token['token'](j)
else:
py_lib[word]=1
j+=1

i+=1

在整個示例數據集中收集庫。

現在我們收集了 GitHub 中所有 Python 倉庫的庫及其提交頻率,我們想在py_lib字典中找到前 10 個庫。我們可以用下面的代碼將前 10 個庫的值收集到一個字典中。

我們可以看到,從示例數據集來看,warningssysdatetime等庫都在 Python 標準庫的前 10 名列表中。

from operator import itemgetter
d=sorted(py_lib.items(), key=itemgetter(1),reverse=True)[:10]
[('warnings', 96.0),
('sys', 73.0),
('datetime', 28.0),
('test', 27.0),
('os', 22.0),
('collections', 18.0),
('io', 16.0),
('gc', 10.0),
('functools', 9.0),
('threading', 7.0)]

基於 GitHub 示例數據集的 Python 十大標準庫。

另外,我們還可以繪製 Python 庫的詞雲圖及其頻率。

import matplotlib.pyplot as plt
from wordcloud import WordCloud
wordcloud = WordCloud(background_color='black',max_font_size = 50)
wordcloud.generate_from_frequencies(frequencies=py_lib)
plt.figure(figsize=(8,6))
plt.imshow(wordcloud, interpolation="bilinear")
plt.axis("off")
plt.show()

基於 GitHub 示例數據集的流行 Python 庫的詞雲圖。

總  結

在本文中,我們嘗試基於一個示例數據集收集 10 個最受歡迎的 Python 庫。這個數據集包含了 GitHub 中 5 個著名的 Python 倉庫最近一年的提交情況。

我們使用 Pydriller 來收集 GitHub 的數據。我們對提交之前和提交之後的源文件抽象語法樹進行了比較,並收集了這些提交中使用的庫列表。最後,我們在詞雲圖中繪製了最流行的 Python 庫。

注:要複製本文的所有代碼,可以在 GitHub 上找到。

作者介紹:

Arghavan Moradi,博士研究生,熱愛學習,喜歡分享。

原文鏈接:

https://towardsdatascience.com/what-are-the-10-most-popular-standard-libraries-in-python-359defb104d6

程序員專欄 掃碼關注填加客服 長按識別下方二維碼進羣

近期精彩內容推薦:  

 看電影前一定要檢查一下域名是不是HTTPS的

 有個大神級女朋友是什麼體驗

 世界上五個最不務正業的科學家!

 魂鬥羅只有128KB爲何可以實現那麼長的劇情


在看點這裏好文分享給更多人↓↓

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章