日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
懶人秘籍:教你如何避免編寫pandas代碼

Pandas在數(shù)據(jù)科學(xué)領(lǐng)域無需介紹,它提供高性能,易于使用的數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)分析工具。但是,在處理過多的數(shù)據(jù)時,單核上的Pandas就顯得心有余而力不足了,大家不得不求助于不同的分布式系統(tǒng)來提高性能。然而,提高性能的權(quán)衡常常伴隨著陡峭的學(xué)習(xí)曲線。

專注于為中小企業(yè)提供做網(wǎng)站、成都網(wǎng)站制作服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)海原免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了上1000+企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

而大家都在盡可能地避免這種懸崖峭壁,結(jié)果可想而知,都轉(zhuǎn)向了如何避免編寫pandas代碼。

在過去4年里,筆者一直使用pandas作為數(shù)據(jù)分析的主要工具。必須承認(rèn),“如何避免編寫pandas代碼”的大部分內(nèi)容來自于使用pandas編程的起步階段。在進(jìn)行代碼審閱時,筆者仍然看到許多經(jīng)驗(yàn)豐富的程序員在看一些熱門“如何避免使用”的帖子。

在本文中,筆者首先展示了一個“如何避免”的例子,然后展示了一個正確的“如何使用”pandas來計(jì)算統(tǒng)計(jì)數(shù)據(jù)的方法。改進(jìn)后,代碼更簡潔、易讀,執(zhí)行更快。報(bào)告時間的格式為: 831 ms ± 25.7 ms per loop,即平均831毫秒,標(biāo)準(zhǔn)偏差為25.7毫秒。每個代碼示例執(zhí)行多次,以計(jì)算準(zhǔn)確的執(zhí)行時間。

和往常一樣,可以下載 JupyterNotebook并在電腦上試運(yùn)行。

開始pandas游戲之旅,請閱讀如下資源:

  • 5個鮮為人知的pandas技巧
  • 使用pandas進(jìn)行探索性數(shù)據(jù)分析

來源:Pexels

設(shè)置

 
 
 
 
  1. from platform importpython_versionimport numpy as np 
  2. import pandas as pdnp.random.seed(42) # set the seed tomake examples repeatable 

樣本數(shù)據(jù)集

樣本數(shù)據(jù)集包含各個城市的預(yù)訂信息,是隨機(jī)的,唯一目的是展示樣本。

數(shù)據(jù)集有三列:

  • id表示唯一的標(biāo)識
  • city表示預(yù)定的城市信息
  • booked perc表示特定時間預(yù)定的百分比

數(shù)據(jù)集有一萬條,這使速度改進(jìn)更加明顯。注意,如果代碼以正確的pandas方式編寫,pandas可以利用DataFrames計(jì)算數(shù)百萬(甚至數(shù)十億)行的統(tǒng)計(jì)數(shù)據(jù)。

 
 
 
 
  1. size = 10000cities =["paris", "barcelona", "berlin", "newyork"]df = pd.DataFrame( 
  2.     {"city": np.random.choice(cities,sizesize=size), "booked_perc": np.random.rand(size)} 
  3. df["id"] = df.index.map(str) +"-" + df.city 
  4. dfdf = df[["id", "city", "booked_perc"]] 
  5. df.head() 

1. 如何避免對數(shù)據(jù)求和

翻滾的熊貓/Reddit

來自Java世界的靈感,把“多行for循環(huán)”應(yīng)用到了Python。

計(jì)算booked perc列的總和,把百分比加起來毫無意義,但無論如何,一起來試試吧,實(shí)踐出真知。

 
 
 
 
  1. %%timeitsuma = 0 
  2. for _, row in df.iterrows(): 
  3.     suma += row.booked_perc766ms ± 20.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 

更符合Python風(fēng)格的方式來對列求和如下:

 
 
 
 
  1. %%timeitsum(booked_perc forbooked_perc in df.booked_perc)989 μs ± 18.5 μs per loop (mean ±std. dev. of 7 runs, 1000 loops each)%%timeitdf.booked_perc.sum()92μs ± 2.21 μs per loop (mean ± std. dev. of 7 runs, 10000 loops each) 

正如預(yù)期的那樣,第一個示例是最慢的——對一萬項(xiàng)求和幾乎需要1秒。第二個例子的速度之快令人驚訝。

正確的方法是使用pandas對數(shù)據(jù)進(jìn)行求和(或?qū)α惺褂萌魏纹渌僮?,這是第三個示例——也是最快的!

2. 如何避免過濾數(shù)據(jù)

玩耍的熊貓/Giphy

盡管在使用pandas之前,筆者已經(jīng)很熟悉numpy,并使用for循環(huán)來過濾數(shù)據(jù)。求和時,還是可以觀察到性能上的差異。

 
 
 
 
  1. %%timeitsuma = 0 
  2. for _, row in df.iterrows(): 
  3.     if row.booked_perc <=0.5: 
  4.         suma += row.booked_perc831ms ± 25.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)%%timeitdf[df.booked_perc<= 0.5].booked_perc.sum()724 μs ± 18.8 μs per loop(mean ± std. dev. of 7 runs, 1000 loops each) 

正如預(yù)期的一樣,第二個例子比第一個例子快很多

如果加入更多的過濾器呢?只需把它們添加到括號里:

 
 
 
 
  1. %%timeitdf[(df.booked_perc <=0.5) & (df.city == 'new york')].booked_perc.sum()1.55ms ± 10.7 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 

3. 如何避免訪問以前的值

翻滾的熊貓/Giphy

你可能會說:好吧,但是如果需要訪問先前某一列的值呢,還是需要一個for循環(huán)。你錯了!

分別使用和不使用for循環(huán)來計(jì)算一行到另一行百分?jǐn)?shù)的改變

 
 
 
 
  1. %%timeitfor i inrange(1, len(df)): 
  2.     df.loc[i,"perc_change"] =  (df.loc[i].booked_perc- df.loc[i - 1].booked_perc) / df.loc[i- 1].booked_perc7.02 s ± 24.4 ms per loop (mean ± std. dev. of 7runs, 1 loop each)%%timeitdf["perc_change"] = df.booked_perc.pct_change()586μs ± 17.3 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 

同樣,第二個例子比第一個使用for循環(huán)的例子快得多。

pandas有許多函數(shù)可以根據(jù)以前的值計(jì)算統(tǒng)計(jì)數(shù)據(jù)(例如shift函數(shù)對值進(jìn)行移位)。這些函數(shù)接受periods參數(shù),可以在計(jì)算中包含以前值的數(shù)量。

4. 如何避免使用復(fù)雜的函數(shù)

來源:墜落的熊貓(國家地理)Giphy

有時需要在DataFrame中使用復(fù)雜函數(shù)(有多個變量的函數(shù))。讓我們將從紐約的booking_perc兩兩相乘,其他設(shè)置為0并且把這列命名為sales_factor。

筆者首先想到的是使用iterrows的for循環(huán)。

 
 
 
 
  1. %%timeitfor i, row in df.iterrows(): 
  2.     if row.city =='new york': 
  3.         df.loc[i, 'sales_factor'] =row.booked_perc * 2 
  4.     else: 
  5.         df.loc[i, 'sales_factor'] =03.58 s ± 48.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 

一個更好的辦法是直接在DataFrame上使用函數(shù)。

 
 
 
 
  1. %%timeitdef calculate_sales_factor(row): 
  2.     if row.city =='new york': 
  3.         return row.booked_perc* 2 
  4.     return 0df['sales_factor'] =df.apply(calculate_sales_factor, axis=1)165 ms ± 2.48 ms per loop(mean ± std. dev. of 7 runs, 10 loops each) 

最快的方法是使用pandas過濾器直接計(jì)算函數(shù)值。

 
 
 
 
  1. %%timeit df.loc[df.city== 'new york', 'sales_factor'] = df[df.city == 'newyork'].booked_perc * 2 
  2. df.sales_factor.fillna(0, inplace=True)3.03 ms ± 85.5 μsper loop (mean ± std. dev. of 7 runs, 100 loops each) 

可以看到從第一個例子到最后一個的加速過程。

當(dāng)解決有3個及3個以上變量的函數(shù)時,可以把它分解為多個pandas表達(dá)式。這比運(yùn)用函數(shù)更快。

 
 
 
 
  1. Eg: f(x, a, b) = (a + b) * x 
  2. df['a_plus_b'] = df['a'] +df['b'] 
  3. df['f'] = df['a_plus_b'] * df['x'] 

5. 如何避免對數(shù)據(jù)進(jìn)行分組

蹭癢熊貓/Giphy

現(xiàn)在可以看到,在開始使用pandas之前,筆者更多依賴于for循環(huán)。至于對數(shù)據(jù)進(jìn)行分組,如果充分發(fā)揮pandas的優(yōu)勢,可以減少代碼行數(shù)。

要計(jì)算如下數(shù)據(jù):

  • 一個城市的平均sales factor
  • 一個城市的首次預(yù)定id
 
 
 
 
  1. %%timeit avg_by_city = {} 
  2. count_by_city = {} 
  3. first_booking_by_city = {}for i, row in df.iterrows(): 
  4.     city = row.city 
  5.     if city in avg_by_city: 
  6.         avg_by_city[city] += row.sales_factor 
  7.         count_by_city[city] += 1 
  8.     else: 
  9.         avg_by_city[city] = row.sales_factor 
  10.         count_by_city[city] = 1 
  11.         first_booking_by_city[city] =row['id']for city, _ in avg_by_city.items(): 
  12.     avg_by_city[city] /=count_by_city[city]878 ms ± 21.4 ms per loop (mean ± std. dev. of 7 runs, 1 loopeach) 

Pandas有分組操作所以不必在DataFrame上進(jìn)行迭代,pandas的分組操作和SQL的GROUP BY語句一樣的。

 
 
 
 
  1. %%timeitdf.groupby('city').sales_factor.mean() 
  2. df.groupby('city').sales_factor.count() 
  3. df.groupby('city').id.first()3.05 ms ± 65.3 μs per loop(mean ± std. dev. of 7 runs, 100 loops each)%%timeitdf.groupby("city").agg({"sales_factor":["mean", "count"], "id": "first"})4.5ms ± 131 μs per loop (mean ± std. dev. of 7 runs, 100 loops each) 

驚奇的是,第三個例子不是最快的,但比第二個例子更簡潔。筆者建議,如果需要加速的代碼,請用第二種方法。

快樂的熊貓/Giphy

最后,小芯的建議是:如果需要使用pandas編寫for循環(huán),那一定存在一種更好的編寫方式。

會存在一些計(jì)算量很大的函數(shù),即使上述的優(yōu)化方法也會無效。那么我們就需要使用最后手段:Cython和Numba。

大家一起來試試這些方法吧,一定會有意想不到的收獲~


標(biāo)題名稱:懶人秘籍:教你如何避免編寫pandas代碼
網(wǎng)頁網(wǎng)址:http://www.dlmjj.cn/article/dpesgig.html