欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python中的探索性數(shù)據(jù)分析(功能式)

 更新時間:2017年12月22日 13:43:56   作者:ymiaqgdc  
這篇文章主要介紹了功能式Python中的探索性數(shù)據(jù)分析的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下

這里有一些技巧來處理日志文件提取。假設我們正在查看一些Enterprise Splunk提取。我們可以用Splunk來探索數(shù)據(jù)?;蛘呶覀兛梢缘玫揭粋€簡單的提取并在Python中擺弄這些數(shù)據(jù)。

在Python中運行不同的實驗似乎比試圖在Splunk中進行這種探索性的操作更有效。主要是因為我們可以無所限制地對數(shù)據(jù)做任何事。我們可以在一個地方創(chuàng)建非常復雜的統(tǒng)計模型。

理論上,我們可以在Splunk中做很多的探索。它有各種報告和分析功能。

但是...

使用Splunk需要假設我們知道我們正在尋找什么。在很多情況下,我們不知道我們在尋找什么:我們正在探索。可能會有一些跡象表明,一些RESTful API處理速度很慢,但還不止于此。我們如何繼續(xù)?

第一步是獲取CSV格式的原始數(shù)據(jù)。怎么辦?

讀取原始數(shù)據(jù)

我們將首先用一些附加函數(shù)來包裝一個CSV.DictReader對象。

面向對象的純粹主義者會反對這個策略。 “為什么不擴展DictReader?”他們問。我沒有一個很好的答案。我傾向于函數(shù)式編程和組件的正交性。對于一個純粹的面向對象的方法,我們不得不使用更復雜的混合來實現(xiàn)這一點。

我們處理日志的一般框架是這樣的。

with open("somefile.csv") as source:
rdr = csv.DictReader(source)

這使我們可以讀取CSV格式的Splunk提取物。我們可以迭代閱讀器中的行。這是訣竅#1。這不是 非常 棘手,但我喜歡它。

with open("somefile.csv") as source:
rdr = csv.DictReader(source)
for row in rdr:
print( "{host} {ResponseTime} {source} {Service}".format_map(row) )

我們可以 - 在一定程度上 - 以有用的格式報告原始數(shù)據(jù)。如果我們想粉飾一下輸出,我們可以改變格式字符串。那就可能是“{主機:30s} {回復時間:8s} {來源:s}”或類似的東西。

過濾

常見的情況是我們提取了太多,但其實只需要看一個子集。我們可以更改Splunk過濾器,但是,在完成我們的探索之前,過量使用過濾器令人討厭。在Python中過濾要容易得多。一旦我們了解到需要什么,就可以在Splunk中完成。

with open("somefile.csv") as source:
rdr = csv.DictReader(source)
rdr_perf_log = (row for row in rdr if row['source'] == 'perf_log')
for row in rdr_perf_log:
print( "{host} {ResponseTime} {Service}".format_map(row) )

我們已經(jīng)加入了一個生成器表達式來過濾源行,能夠處理一個有意義的子集。

投影

在某些情況下,我們會添加額外的源數(shù)據(jù)列,這些列我們并不想使用。所以將通過對每一行進行投影來消除這些數(shù)據(jù)。

原則上,Splunk從不產(chǎn)生空列。但是,RESTful API日志可能會導致數(shù)據(jù)集中包含大量列標題,這些列標題是基于請求URI一部分的代理鍵。這些列將包含來自使用該代理鍵的一個請求的一行數(shù)據(jù)。對于其他行,在這一列中沒有任何用處。所以要刪除這些空列。

我們也可以用一個生成器表達式來做到這一點,但是它會變得有點長。生成器函數(shù)更容易閱讀.

def project(reader):
for row in reader:
yield {k:v for k,v in row.items() if v}

我們已經(jīng)從原始閱讀器中的一部分項目構建了一個新的行字典。我們可以使用它來包裝我們的過濾器的輸出。

with open("somefile.csv") as source:
rdr = csv.DictReader(source)
rdr_perf_log = (row for row in rdr if row['source'] == 'perf_log')
for row in project(rdr_perf_log):
print( "{host} {ResponseTime} {Service}".format_map(row) )

這將減少在for語句內部可見的未使用的列。

符號更改

row['source']符號會變得比較笨重。使用types.SimpleNamespace比用字典 更好。這使得我們可以使用row.source。

這是一個很酷的技巧來創(chuàng)造更有用的東西。

rdr_ns= (types.SimpleNamespace(**row) forrowinreader)

我們可以將其折疊成這樣的步驟序列。

with open("somefile.csv") as source:
rdr = csv.DictReader(source)
rdr_perf_log = (row for row in rdr if row['source'] == 'perf_log')
rdr_proj = project(rdr_perf_log)
rdr_ns = (types.SimpleNamespace(**row) for row in rdr_proj)
for row in rdr_ns:
print( "{host} {ResponseTime} {Service}".format_map(vars(row)) )

請注意我們對format_map()方法的小改動。從SimpleNamespace的屬性中,我們添加了vars()函數(shù)來提取字典 。

我們可以用其他函數(shù)把它寫成一個函數(shù)來保留句法對稱性。

def ns_reader(reader):
return (types.SimpleNamespace(**row) for row in reader)

的確,我們可以把它寫成一個像函數(shù)一樣使用的lambda結構

ns_reader = lambda reader: (types.SimpleNamespace(**row) for row in reader)

雖然ns_reader()函數(shù)和ns_reader()lambda的使用方式相同,但為lambda編寫文檔字符串和doctest單元測試稍微困難一些。出于這個原因,應該避免使用lambda結構。

我們可以使用map(lambda row:types.SimpleNamespace(** row),reader)。有些人喜歡這個發(fā)生器表達式。

我們可以用一個適當?shù)膄or語句和一個內部的yield語句,但是從一個小的東西里寫大的語句似乎沒有什么好處。

我們有很多選擇,因為Python提供了如此多的函數(shù)式編程功能。雖然我們不會經(jīng)常把Python視作一種功能性語言。但我們有多種方法來處理簡單的映射。

映射:轉換和派生數(shù)據(jù)

我們經(jīng)常會有一個非常明顯的數(shù)據(jù)轉換列表。此外,我們將有一個衍生的數(shù)據(jù)項目越來越多的列表。衍生項目將是動態(tài)的,并基于我們正在測試的不同假設。每當我們有一個實驗或問題,我們可能會改變派生的數(shù)據(jù)。

這些步驟中的每一個:過濾,投影,轉換和派生都是map-reduce管道的“map”部分的階段。我們可以創(chuàng)建一些較小的函數(shù),并將其應用于map()。因為我們正在更新一個有狀態(tài)的對象,所以我們不能使用一般的map()函數(shù)。如果我們想實現(xiàn)一個更純粹的函數(shù)式編程風格,我們將使用一個不可變的namedtuple而不是一個可變的SimpleNamespace。

def convert(reader):
for row in reader:
row._time = datetime.datetime.strptime(row.Time, "%Y-%m-%dT%H:%M:%S.%F%Z")
row.response_time = float(row.ResponseTime)
yield row

在我們探索的過程中,我們將調整這個轉換函數(shù)的主體。也許我們將從一些最小的轉換和派生開始。我們將用一些“這些是正確的?”的問題來繼續(xù)探索。當我們發(fā)現(xiàn)不工作時,我們會從中取出一些。

我們的整體處理過程如下所示:

with open("somefile.csv") as source:
rdr = csv.DictReader(source)
rdr_perf_log = (row for row in rdr if row['source'] == 'perf_log')
rdr_proj = project(rdr_perf_log)
rdr_ns = (types.SimpleNamespace(**row) for row in rdr_proj)
rdr_converted = convert(rdr_ns)
for row in rdr_converted:
row.start_time = row._time - datetime.timedelta(seconds=row.response_time)
row.service = some_mapping(row.Service)
print( "{host:30s} {start_time:%H:%M:%S} {response_time:6.3f} {service}".format_map(vars(row)) )

請注意語句主體的變化。convert()函數(shù)產(chǎn)生我們確定的值。我們已經(jīng)在for循環(huán)中添加了一些額外的變量,我們不能100%確定。在更新convert()函數(shù)之前,我們會看看它們是否有用(甚至是正確的)。

減量

在減量方面,我們可以采取稍微不同的加工方式。我們需要重構我們之前的例子,并把它變成一個生成器函數(shù)。

def converted_log(some_file):
with open(some_file) as source:
rdr = csv.DictReader(source)
rdr_perf_log = (row for row in rdr if row['source'] == 'perf_log')
rdr_proj = project(rdr_perf_log)
rdr_ns = (types.SimpleNamespace(**row) for row in rdr_proj)
rdr_converted = convert(rdr_ns)
for row in rdr_converted:
row.start_time = row._time - datetime.timedelta(seconds=row.response_time)
row.service = some_mapping(row.Service)
yield row

接著用一個yield代替了print()。

這是重構的另一部分。

for row in converted_log("somefile.csv"):
print( "{host:30s} {start_time:%H:%M:%S} {response_time:6.3f} {service}".format_map(vars(row)) )

理想情況下,我們所有的編程都是這樣的。我們使用生成器函數(shù)來生成數(shù)據(jù)。數(shù)據(jù)的最終顯示保持完全分離。這使我們可以更自由地重構和改變處理。

現(xiàn)在我們可以做一些事情,例如將行收集到Counter()對象中,或者可能計算一些統(tǒng)計信息。我們可以使用defaultdict(list)按服務對行進行分組。

by_service= defaultdict(list)
for row in converted_log("somefile.csv"):
by_service[row.service] = row.response_time
for svc in sorted(by_service):
m = statistics.mean( by_service[svc] )
print( "{svc:15s} {m:.2f}".format_map(vars()) )

我們決定在這里創(chuàng)建具體的列表對象。我們可以使用itertools按服務分組響應時間。它看起來像是正確的函數(shù)式編程,但是這種實施在Pythonic函數(shù)式編程形式中指出了一些限制。要么我們必須對數(shù)據(jù)進行排序(創(chuàng)建列表對象),要么在分組數(shù)據(jù)時創(chuàng)建列表。為了做好幾個不同的統(tǒng)計,通過創(chuàng)建具體的列表來分組數(shù)據(jù)通常更容易。

我們現(xiàn)在正在做兩件事情,而不是簡單地打印行對象。

創(chuàng)建一些局部變量,如svc和m。我們可以很容易地添加變化或其他措施。

使用沒有參數(shù)的vars()函數(shù),它會從局部變量中創(chuàng)建一個字典。

這個使用vars()而沒有參數(shù)的行為就像locals()一樣是一個方便的技巧。它允許我們簡單地創(chuàng)建我們想要的任何局部變量,并將它們包含在格式化輸出中。我們可以侵入我們認為可能相關的各種統(tǒng)計方法中。

既然我們的基本處理循環(huán)是針對converted_log(“somefile.csv”)中的行,我們可以通過一個小小的,易于修改的腳本探索很多處理選擇。我們可以探索一些假設來確定為什么某些RESTful API處理速度慢,而其他處理速度則很快。

總結

以上所述是小編給大家介紹的Python中的探索性數(shù)據(jù)分析(功能式),希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家的支持!

相關文章

  • python中time庫的實例使用方法

    python中time庫的實例使用方法

    在本篇文章里的是關于python中time庫的實例使用方法以及相關知識點,有需要的朋友們可以學習下。
    2019-10-10
  • 如何利用python實現(xiàn)圖片批處理

    如何利用python實現(xiàn)圖片批處理

    這篇文章主要給大家介紹了關于如何利用python實現(xiàn)圖片批處理的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • Python過濾txt文件內重復內容的方法

    Python過濾txt文件內重復內容的方法

    今天小編就為大家分享一篇Python過濾txt文件內重復內容的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-10-10
  • python遠程調用rpc模塊xmlrpclib的方法

    python遠程調用rpc模塊xmlrpclib的方法

    今天小編就為大家分享一篇python遠程調用rpc模塊xmlrpclib的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • 使用Pytorch導出自定義ONNX算子的示例代碼

    使用Pytorch導出自定義ONNX算子的示例代碼

    這篇文章主要介紹了使用Pytorch導出自定義ONNX算子的示例代碼,下面給出個具體應用中的示例:需要導出pytorch的affine_grid算子,但在pytorch的2.0.1版本中又無法正常導出該算子,故可通過如下自定義算子代碼導出,需要的朋友可以參考下
    2024-03-03
  • 快速進修Python指南之控制if-else循環(huán)技巧

    快速進修Python指南之控制if-else循環(huán)技巧

    這篇文章主要為大家介紹了Java開發(fā)者的Python快速進修指南之控制之if-else和循環(huán)技巧示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • Python之串口收發(fā)的異步程序

    Python之串口收發(fā)的異步程序

    這篇文章主要介紹了Python之串口收發(fā)的異步程序,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Python利用代碼計算2個坐標之間的距離

    Python利用代碼計算2個坐標之間的距離

    這篇文章主要介紹了Python利用代碼計算2個坐標之間的距離,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Python實現(xiàn)自定義函數(shù)的5種常見形式分析

    Python實現(xiàn)自定義函數(shù)的5種常見形式分析

    這篇文章主要介紹了Python實現(xiàn)自定義函數(shù)的5種常見形式,結合實例形式較為詳細的分析了Python自定義函數(shù)相關的參數(shù)、默認值、隱函數(shù)等相關操作技巧與注意事項,需要的朋友可以參考下
    2018-06-06
  • python基礎:面向對象詳解

    python基礎:面向對象詳解

    這篇文章主要介紹了Python面向對象的相關內容,如果您想對Python編程的基礎部分有所了解,這篇文章是值得一看的,需要的朋友可以參考下。
    2021-10-10

最新評論