<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>

          玩轉(zhuǎn) Pandas 的 Groupby 操作

          共 6956字,需瀏覽 14分鐘

           ·

          2020-12-11 01:46

          作者:Lemon

          來源:Python數(shù)據(jù)之道

          玩轉(zhuǎn) Pandas 的 Groupby 操作

          大家好,我是 Lemon,今天來跟大家分享下 pandas 中 groupby 的用法。

          Pandas 的 groupby() 功能很強(qiáng)大,用好了可以方便的解決很多問題,在數(shù)據(jù)處理以及日常工作中經(jīng)常能施展拳腳。

          今天,我們一起來領(lǐng)略下 groupby() 的魅力吧。

          首先,引入相關(guān) package :

          import?pandas?as?pd
          import?numpy?as?np

          groupby 的基礎(chǔ)操作

          經(jīng)常用 groupby 對(duì) pandas 中 dataframe 的各列進(jìn)行統(tǒng)計(jì),包括求和、求均值等。

          In?[2]:?df?=?pd.DataFrame({'A':?['a',?'b',?'a',?'c',?'a',?'c',?'b',?'c'],?
          ???...:????????????????????'B':?[2,?8,?1,?4,?3,?2,?5,?9],?
          ???...:????????????????????'C':?[102,?98,?107,?104,?115,?87,?92,?123]})
          ???...:?df
          ???...:?

          Out[2]:?
          ???A??B????C
          0??a??2??102
          1??b??8???98
          2??a??1??107
          3??c??4??104
          4??a??3??115
          5??c??2???87
          6??b??5???92
          7??c??9??123

          按 A 列分組(groupby),獲取其他列的均值

          df.groupby('A').mean()

          Out[3]:?
          ?????B???????????C
          A?????????????????
          a??2.0??108.000000
          b??6.5???95.000000
          c??5.0??104.666667

          按多列進(jìn)行分組(groupby)

          df.groupby(['A','B']).mean()

          Out[4]:?
          ???????C
          A?B?????
          a?1??107
          ??2??102
          ??3??115
          b?5???92
          ??8???98
          c?2???87
          ??4??104
          ??9??123

          分組后選擇列進(jìn)行運(yùn)算

          分組后,可以選取單列數(shù)據(jù),或者多個(gè)列組成的列表(list)進(jìn)行運(yùn)算

          In?[5]:?df?=?pd.DataFrame([[1,?1,?2],?[1,?2,?3],?[2,?3,?4]],?columns=["A",?"B",?"C"])
          ???...:?df
          ???...:?

          Out[5]:?
          ???A??B??C
          0??1??1??2
          1??1??2??3
          2??2??3??4

          In?[6]:?g?=?df.groupby("A")

          In?[7]:?g['B'].mean()?#?僅選擇B列

          Out[7]:?
          A
          1????1.5
          2????3.0
          Name:?B,?dtype:?float64

          In?[8]:?g[['B',?'C']].mean()?#?選擇B、C列

          Out[8]:?
          ?????B????C
          A??????????
          1??1.5??2.5
          2??3.0??4.0

          可以針對(duì)不同的列選用不同的聚合方法

          In?[9]:?g.agg({'B':'mean',?'C':'sum'})

          Out[9]:?
          ?????B??C
          A????????
          1??1.5??5
          2??3.0??4

          聚合方法

          聚合方法有 size() 和 count() 。

          size 跟 count 的區(qū)別:size 計(jì)數(shù)時(shí)包含 NaN 值,而 count 不包含 NaN值

          In?[10]:?df?=?pd.DataFrame({"Name":["Alice",?"Bob",?"Mallory",?"Mallory",?"Bob"?,?"Mallory"],
          ????...:??????????????????"City":["Seattle",?"Seattle",?"Portland",?"Seattle",?"Seattle",?"Portland"],
          ????...:??????????????????"Val":[4,3,3,np.nan,np.nan,4]})
          ????...:?
          ????...:?df
          ????...:?
          Out[10]:?
          ???????City?????Name??Val
          0???Seattle????Alice??4.0
          1???Seattle??????Bob??3.0
          2??Portland??Mallory??3.0
          3???Seattle??Mallory??NaN
          4???Seattle??????Bob??NaN
          5??Portland??Mallory??4.0

          count()

          In?[11]:?df.groupby(["Name",?"City"],?as_index=False)['Val'].count()

          Out[11]:?
          ??????Name??????City??Val
          0????Alice???Seattle????1
          1??????Bob???Seattle????1
          2??Mallory??Portland????2
          3??Mallory???Seattle????0

          size()

          In?[12]:?df.groupby(["Name",?"City"])['Val'].size().reset_index(name='Size')

          Out[12]:?
          ??????Name??????City??Size
          0????Alice???Seattle?????1
          1??????Bob???Seattle?????2
          2??Mallory??Portland?????2
          3??Mallory???Seattle?????1

          分組運(yùn)算方法 agg()

          針對(duì)某列使用agg()時(shí)進(jìn)行不同的統(tǒng)計(jì)運(yùn)算

          In?[13]:?df?=?pd.DataFrame({'A':?list('XYZXYZXYZX'),?'B':?[1,?2,?1,?3,?1,?2,?3,?3,?1,?2],?
          ????...:????????????????????????????'C':?[12,?14,?11,?12,?13,?14,?16,?12,?10,?19]})
          ????...:?df
          ????...:?
          Out[13]:?
          ???A??B???C
          0??X??1??12
          1??Y??2??14
          2??Z??1??11
          3??X??3??12
          4??Y??1??13
          5??Z??2??14
          6??X??3??16
          7??Y??3??12
          8??Z??1??10
          9??X??2??19

          In?[14]:?df.groupby('A')['B'].agg({'mean':np.mean,?'standard?deviation':?np.std})

          Out[14]:?
          ???????mean??standard?deviation
          A??????????????????????????????
          X??2.250000????????????0.957427
          Y??2.000000????????????1.000000
          Z??1.333333????????????0.577350

          針對(duì)不同的列應(yīng)用多種不同的統(tǒng)計(jì)方法

          In?[15]:?df.groupby('A').agg({'B':[np.mean,?'sum'],?'C':['count',np.std]})

          Out[15]:?
          ??????????B?????????C??????????
          ???????mean?sum?count???????std
          A??????????????????????????????
          X??2.250000???9?????4??3.403430
          Y??2.000000???6?????3??1.000000
          Z??1.333333???4?????3??2.081666

          分組運(yùn)算方法 apply()

          In?[16]:?df?=?pd.DataFrame({'A':?list('XYZXYZXYZX'),?'B':?[1,?2,?1,?3,?1,?2,?3,?3,?1,?2],?
          ????...:????????????????????????????'C':?[12,?14,?11,?12,?13,?14,?16,?12,?10,?19]})
          ????...:?df
          ????...:?
          Out[16]:?
          ???A??B???C
          0??X??1??12
          1??Y??2??14
          2??Z??1??11
          3??X??3??12
          4??Y??1??13
          5??Z??2??14
          6??X??3??16
          7??Y??3??12
          8??Z??1??10
          9??X??2??19

          In?[17]:?df.groupby('A').apply(np.mean)
          ????...:?#?跟下面的方法的運(yùn)行結(jié)果是一致的
          ????...:?#?df.groupby('A').mean()
          Out[17]:?
          ??????????B??????????C
          A?????????????????????
          X??2.250000??14.750000
          Y??2.000000??13.000000
          Z??1.333333??11.666667

          apply() 方法可以應(yīng)用 lambda 函數(shù),舉例如下:

          In?[18]:?df.groupby('A').apply(lambda?x:?x['C']-x['B'])
          Out[18]:?
          A???
          X??0????11
          ???3?????9
          ???6????13
          ???9????17
          Y??1????12
          ???4????12
          ???7?????9
          Z??2????10
          ???5????12
          ???8?????9
          dtype:?int64

          In?[19]:?df.groupby('A').apply(lambda?x:?(x['C']-x['B']).mean())
          Out[19]:?
          A
          X????12.500000
          Y????11.000000
          Z????10.333333
          dtype:?float64

          分組運(yùn)算方法 transform()

          前面進(jìn)行聚合運(yùn)算的時(shí)候,得到的結(jié)果是一個(gè)以分組名為 index 的結(jié)果對(duì)象。如果我們想使用原數(shù)組的 index 的話,就需要進(jìn)行 merge 轉(zhuǎn)換。transform(func, *args, **kwargs) 方法簡化了這個(gè)過程,它會(huì)把 func 參數(shù)應(yīng)用到所有分組,然后把結(jié)果放置到原數(shù)組的 index 上(如果結(jié)果是一個(gè)標(biāo)量,就進(jìn)行廣播):

          In?[20]:?df?=?pd.DataFrame({'group1'?:??['A',?'A',?'A',?'A',
          ????...:????????????????????????????????'B',?'B',?'B',?'B'],
          ????...:????????????????????'group2'?:??['C',?'C',?'C',?'D',
          ????...:????????????????????????????????'E',?'E',?'F',?'F'],
          ????...:????????????????????'B'??????:??['one',?np.NaN,?np.NaN,?np.NaN,
          ????...:?????????????????????????????????np.NaN,?'two',?np.NaN,?np.NaN],
          ????...:????????????????????'C'??????:??[np.NaN,?1,?np.NaN,?np.NaN,
          ????...:????????????????????????????????np.NaN,?np.NaN,?np.NaN,?4]})???????????
          ????...:?df
          ????...:?
          Out[20]:?
          ?????B????C?group1?group2
          0??one??NaN??????A??????C
          1??NaN??1.0??????A??????C
          2??NaN??NaN??????A??????C
          3??NaN??NaN??????A??????D
          4??NaN??NaN??????B??????E
          5??two??NaN??????B??????E
          6??NaN??NaN??????B??????F
          7??NaN??4.0??????B??????F

          In?[21]:?df.groupby(['group1',?'group2'])['B'].transform('count')
          Out[21]:?
          0????1
          1????1
          2????1
          3????0
          4????1
          5????1
          6????0
          7????0
          Name:?B,?dtype:?int64

          In?[22]:?df['count_B']=df.groupby(['group1',?'group2'])['B'].transform('count')
          ????...:?df
          ????...:?
          Out[22]:?
          ?????B????C?group1?group2??count_B
          0??one??NaN??????A??????C????????1
          1??NaN??1.0??????A??????C????????1
          2??NaN??NaN??????A??????C????????1
          3??NaN??NaN??????A??????D????????0
          4??NaN??NaN??????B??????E????????1
          5??two??NaN??????B??????E????????1
          6??NaN??NaN??????B??????F????????0
          7??NaN??4.0??????B??????F????????0

          上面運(yùn)算的結(jié)果分析:{'group1':'A', 'group2':'C'} 的組合共出現(xiàn)3次,即 index為 0,1,2。對(duì)應(yīng) "B" 列的值分別是 "one","NaN","NaN",由于 count() 計(jì)數(shù)時(shí)不包括NaN值,因此 {'group1':'A', 'group2':'C'} 的 count 計(jì)數(shù)值為 1 。

          transform() 方法會(huì)將該計(jì)數(shù)值在 dataframe 中所有涉及的 rows 都顯示出來(我理解應(yīng)該就進(jìn)行廣播)

          將某列數(shù)據(jù)按數(shù)據(jù)值分成不同范圍段進(jìn)行分組(groupby)運(yùn)算

          In?[23]:?np.random.seed(0)
          ????...:?df?=?pd.DataFrame({'Age':?np.random.randint(20,?70,?100),?
          ????...:????????????????????'Sex':?np.random.choice(['Male',?'Female'],?100),?
          ????...:????????????????????'number_of_foo':?np.random.randint(1,?20,?100)})
          ????...:?df.head()
          ????...:?
          Out[23]:?
          ???Age?????Sex??number_of_foo
          0???64??Female?????????????14
          1???67??Female?????????????14
          2???20??Female?????????????12
          3???23????Male?????????????17
          4???23??Female?????????????15

          這里將 “Age” 列分成三類,有兩種方法可以實(shí)現(xiàn):

          (a)bins=4

          (b)bins=[19, 40, 65, np.inf]

          In?[24]:?pd.cut(df['Age'],?bins=4)
          Out[24]:?
          ...

          In?[25]:?pd.cut(df['Age'],?bins=[19,40,65,np.inf])

          分組結(jié)果范圍結(jié)果如下:

          In?[26]:?age_groups?=?pd.cut(df['Age'],?bins=[19,40,65,np.inf])
          ????...:?df.groupby(age_groups).mean()

          運(yùn)行結(jié)果如下:

          按‘Age’分組范圍和性別(sex)進(jìn)行制作交叉表

          In?[27]:?pd.crosstab(age_groups,?df['Sex'])

          運(yùn)行結(jié)果如下:

          往期推薦:

          收藏 | 49 個(gè) Python 學(xué)習(xí)資源

          我都逛哪些技術(shù)網(wǎng)站?(程序員必備58個(gè)網(wǎng)站匯總)

          肝!精心整理了 50 個(gè)數(shù)據(jù)源網(wǎng)站!


          ?分享、點(diǎn)贊、在看,給個(gè)三連擊唄!??
          瀏覽 46
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  成人黄页网 | 最近最好的2019中文 | 蘑菇 视频成人精品网站 | 无码中字成人AV | 久久视频欧美 |