<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Pandas數(shù)據(jù)分析——超好用的Groupby詳解

          共 4515字,需瀏覽 10分鐘

           ·

          2020-01-15 23:25


          963b770689242614a661e694ca3e5021.webp


          ? ? ?作者:易執(zhí)


          ? ? ?來源:Python讀財


          在日常的數(shù)據(jù)分析中,經(jīng)常需要將數(shù)據(jù)根據(jù)某個(多個)字段劃分為不同的群體(group)進行分析,如電商領(lǐng)域?qū)⑷珖目備N售額根據(jù)省份進行劃分,分析各省銷售額的變化情況,社交領(lǐng)域?qū)⒂脩舾鶕?jù)畫像(性別、年齡)進行細分,研究用戶的使用情況和偏好等。在Pandas中,上述的數(shù)據(jù)處理操作主要運用groupby完成,這篇文章就介紹一下groupby的基本原理及對應(yīng)的aggtransformapply操作。

          為了后續(xù)圖解的方便,采用模擬生成的10個樣本數(shù)據(jù),代碼和數(shù)據(jù)如下:

          company=["A","B","C"]

          data=pd.DataFrame({
          ????"company":[company[x]?for?x?in?np.random.randint(0,len(company),10)],
          ????"salary":np.random.randint(5,50,10),
          ????"age":np.random.randint(15,50,10)
          }
          )

          784e4baa95c7df746b24ccea9d07a2fb.webp


          groupby的基本原理

          在Pandas中,實現(xiàn)分組操作的代碼很簡單,僅需一行代碼,在這里,將上面的數(shù)據(jù)集按照company字段進行劃分:

          In?[5]:?group?=?data.groupby("company")

          將上述代碼輸入ipython后,會得到一個DataFrameGroupBy對象

          In?[6]:?group
          Out[6]:?0x000002B7E2650240>

          那這個生成的DataFrameGroupBy是啥呢?對data進行了groupby后發(fā)生了什么?ipython所返回的結(jié)果是其內(nèi)存地址,并不利于直觀地理解,為了看看group內(nèi)部究竟是什么,這里把group轉(zhuǎn)換成list的形式來看一看:

          In?[8]:?list(group)
          Out[8]:
          [('A',???company??salary??age
          ??3???????A??????20???22
          ??6???????A??????23???33),?
          ?('B',???company??salary??age
          ??4???????B??????10???17
          ??5???????B??????21???40
          ??8???????B???????8???30),?
          ?('C',???company??salary??age
          ??0???????C??????43???35
          ??1???????C??????17???25
          ??2???????C???????8???30
          ??7???????C??????49???19)]

          轉(zhuǎn)換成列表的形式后,可以看到,列表由三個元組組成,每個元組中,第一個元素是組別(這里是按照company進行分組,所以最后分為了A,B,C),第二個元素的是對應(yīng)組別下的DataFrame,整個過程可以圖解如下:

          9732541af94b3dbc59bb8ffe0db765f3.webp

          總結(jié)來說,groupby的過程就是將原有的DataFrame按照groupby的字段(這里是company),劃分為若干個分組DataFrame,被分為多少個組就有多少個分組DataFrame所以說,在groupby之后的一系列操作(如aggapply等),均是基于分組DataFrame的操作。理解了這點,也就基本摸清了Pandas中groupby操作的主要原理。下面來講講groupby之后的常見操作。


          agg分組聚合


          聚合操作是groupby后常見的操作,會寫SQL的朋友對此應(yīng)該是非常熟悉了。聚合操作可以用來求和、均值、最大值、最小值等,下面的表格列出了Pandas中常見的聚合操作。


          5305df25da82f7d3b46a816a3fcac0b9.webp

          針對樣例數(shù)據(jù)集,如果我想計算不同公司員工的平均年齡和平均薪水,可以按照下方的代碼進行:

          In?[12]:?data.groupby("company").agg('mean')Out[12]:
          ?????????salary????age
          company
          A?????????21.50??27.50
          B?????????13.00??29.00
          C?????????29.25??27.25

          如果想對針對不同的列求不同的值,比如要計算不同公司員工的平均年齡以及薪水的中位數(shù),可以利用字典指定進行聚合操作:

          In?[17]:?data.groupby('company').agg({'salary':'median','age':'mean'})
          Out[17]:
          ?????????salary????age
          company
          A??????????21.5??27.50
          B??????????10.0??29.00
          C??????????30.0??27.25

          agg聚合過程可以圖解如下(第二個例子為例):

          b3208b109273836e4112c24b6ad28251.webp



          transform

          transform是一種什么數(shù)據(jù)操作?和agg有什么區(qū)別呢?為了更好地理解transformagg的不同,下面從實際的應(yīng)用場景出發(fā)進行對比。

          在上面的agg中,我們學(xué)會了如何求不同公司員工的平均薪水,如果現(xiàn)在需要在原數(shù)據(jù)集中新增一列avg_salary,代表員工所在的公司的平均薪水(相同公司的員工具有一樣的平均薪水),該怎么實現(xiàn)呢?如果按照正常的步驟來計算,需要先求得不同公司的平均薪水,然后按照員工和公司的對應(yīng)關(guān)系填充到對應(yīng)的位置,不用transform的話,實現(xiàn)代碼如下:

          In?[21]:?avg_salary_dict?=?data.groupby('company')['salary'].mean().to_dict()

          In?[22]:?data['avg_salary']?=?data['company'].map(avg_salary_dict)

          In?[23]:?data
          Out[23]:
          ??company??salary??age??avg_salary
          0???????C??????43???35???????29.25
          1???????C??????17???25???????29.25
          2???????C???????8???30???????29.25
          3???????A??????20???22???????21.50
          4???????B??????10???17???????13.00
          5???????B??????21???40???????13.00
          6???????A??????23???33???????21.50
          7???????C??????49???19???????29.25
          8???????B???????8???30???????13.00

          如果使用transform的話,僅需要一行代碼:

          In?[24]:?data['avg_salary']?=?data.groupby('company')['salary'].transform('mean')

          In?[25]:?data
          Out[25]:
          ??company??salary??age??avg_salary
          0???????C??????43???35???????29.25
          1???????C??????17???25???????29.25
          2???????C???????8???30???????29.25
          3???????A??????20???22???????21.50
          4???????B??????10???17???????13.00
          5???????B??????21???40???????13.00
          6???????A??????23???33???????21.50
          7???????C??????49???19???????29.25
          8???????B???????8???30???????13.00

          還是以圖解的方式來看看進行groupbytransform的實現(xiàn)過程(為了更直觀展示,圖中加入了company列,實際按照上面的代碼只有salary列):

          daf6aab1cdac1f8ca3be4954e7ee9a29.webp

          圖中的大方框是transformagg所不一樣的地方,對agg而言,會計算得到ABC公司對應(yīng)的均值并直接返回,但對transform而言,則會對每一條數(shù)據(jù)求得相應(yīng)的結(jié)果,同一組內(nèi)的樣本會有相同的值,組內(nèi)求完均值后會按照原索引的順序返回結(jié)果,如果有不理解的可以拿這張圖和agg那張對比一下。


          apply

          apply應(yīng)該是大家的老朋友了,它相比aggtransform而言更加靈活,能夠傳入任意自定義的函數(shù),實現(xiàn)復(fù)雜的數(shù)據(jù)操作。在Pandas數(shù)據(jù)處理三板斧,你會幾板?中,介紹了apply的使用,那在groupby后使用apply和之前所介紹的有什么區(qū)別呢?

          區(qū)別是有的,但是整個實現(xiàn)原理是基本一致的。兩者的區(qū)別在于,對于groupby后的apply,以分組后的分組DataFrame作為參數(shù)傳入指定函數(shù)的,基本操作單位是DataFrame,而之前介紹的apply的基本操作單位是Series。還是以一個案例來介紹groupby后的apply用法。

          假設(shè)我現(xiàn)在需要獲取各個公司年齡最大的員工的數(shù)據(jù),該怎么實現(xiàn)呢?可以用以下代碼實現(xiàn):

          In?[38]:?def?get_oldest_staff(x):
          ????...:?????df?=?x.sort_values(by?=?'age',ascending=True)
          ????...:?????return?df.iloc[-1,:]
          ????...:

          In?[39]:?oldest_staff?=?data.groupby('company',as_index=False).apply(get_oldest_staff)

          In?[40]:?oldest_staff
          Out[40]:
          ??company??salary??age??
          0???????A??????23???33???????
          1???????B??????21???40???????
          2???????C??????43???35??????

          這樣便得到了每個公司年齡最大的員工的數(shù)據(jù),整個流程圖解如下:

          263434f55c105a8adb7d7a5257ed8f74.webp可以看到,此處的apply和上篇文章中所介紹的作用原理基本一致,只是傳入函數(shù)的參數(shù)由Series變?yōu)榱舜颂幍?/span>分組DataFrame

          最后,關(guān)于apply的使用,這里有個小建議,雖然說apply擁有更大的靈活性,但apply的運行效率會比aggtransform更慢。所以,groupby之后能用aggtransform解決的問題還是優(yōu)先使用這兩個方法,實在解決不了了才考慮使用apply進行操作。

          ◆?◆?◆ ?◆?



          長按二維碼關(guān)注我們



          數(shù)據(jù)森麟公眾號的交流群已經(jīng)建立,許多小伙伴已經(jīng)加入其中,感謝大家的支持。大家可以在群里交流關(guān)于數(shù)據(jù)分析&數(shù)據(jù)挖掘的相關(guān)內(nèi)容,還沒有加入的小伙伴可以掃描下方管理員二維碼,進群前一定要關(guān)注公眾號奧,關(guān)注后讓管理員幫忙拉進群,期待大家的加入。


          管理員二維碼:


          猜你喜歡

          ?笑死人不償命的知乎沙雕問題排行榜

          ?用Python扒出B站那些“驚為天人”的阿婆主!

          ?互聯(lián)網(wǎng)大佬學(xué)歷&背景大揭秘,看看是你的老鄉(xiāng)還是校友

          ?上萬條數(shù)據(jù)撕開微博熱搜的真相!

          ?你相信逛B站也能學(xué)編程嗎??

          瀏覽 91
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人黄频 | 天天色天天干天天 | 三级黄,色毛片 | 爆操美女视频 | wWW香焦yeyeLu |