DataWhale組隊(duì)學(xué)習(xí)之分組

參考datawhale:https://datawhalechina.github.io/joyful-pandas/build/html/%E7%9B%AE%E5%BD%95/ch4.html#id2

In [1]: import numpy as np
In [2]: import pandas as pd

一、分組模式及其對(duì)象

  1. 分組的一般模式

分組操作在日常生活中使用極其廣泛,例如:

  • 依據(jù) 性別 分組,統(tǒng)計(jì)全國(guó)人口 壽命 的 平均值

  • 依據(jù) 季節(jié) 分組,對(duì)每一個(gè)季節(jié)的 溫度 進(jìn)行 組內(nèi)標(biāo)準(zhǔn)化

  • 依據(jù) 班級(jí) 分組,篩選出組內(nèi) 數(shù)學(xué)分?jǐn)?shù) 的 平均值超過(guò)80分的班級(jí)

從上述的幾個(gè)例子中不難看出,想要實(shí)現(xiàn)分組操作,必須明確三個(gè)要素:分組依據(jù) 、 數(shù)據(jù)來(lái)源 、 操作及其返回結(jié)果 。同時(shí)從充分性的角度來(lái)說(shuō),如果明確了這三方面,就能確定一個(gè)分組操作,從而分組代碼的一般模式即:

df.groupby(分組依據(jù))[數(shù)據(jù)來(lái)源].使用操作

例如第一個(gè)例子中的代碼就應(yīng)該如下:

df.groupby('Gender')['Longevity'].mean()

現(xiàn)在返回到學(xué)生體測(cè)的數(shù)據(jù)集上,如果想要按照性別統(tǒng)計(jì)身高中位數(shù),就可以如下寫出:

In [3]: df = pd.read_csv('data/learn_pandas.csv')
In [4]: df.groupby('Gender')['Height'].median()
Out[4]:
Gender
Female    159.6
Male      173.4
Name: Height, dtype: float64
  1. 分組依據(jù)的本質(zhì)
    前面提到的若干例子都是以單一維度進(jìn)行分組的,比如根據(jù)性別,如果現(xiàn)在需要根據(jù)多個(gè)維度進(jìn)行分組,該如何做?事實(shí)上,只需在 groupby 中傳入相應(yīng)列名構(gòu)成的列表即可。例如,現(xiàn)希望根據(jù)學(xué)校和性別進(jìn)行分組,統(tǒng)計(jì)身高的均值就可以如下寫出:
In [5]: df.groupby(['School', 'Gender'])['Height'].mean()
Out[5]: 
School                         Gender
Fudan University               Female    158.776923
                               Male      174.212500
Peking University              Female    158.666667
                               Male      172.030000
Shanghai Jiao Tong University  Female    159.122500
                               Male      176.760000
Tsinghua University            Female    159.753333
                               Male      171.638889
Name: Height, dtype: float64

目前為止, groupby 的分組依據(jù)都是直接可以從列中按照名字獲取的,那如果希望通過(guò)一定的復(fù)雜邏輯來(lái)分組,例如根據(jù)學(xué)生體重是否超過(guò)總體均值來(lái)分組,同樣還是計(jì)算身高的均值。

首先應(yīng)該先寫出分組條件:

In [6]: condition = df.Weight > df.Weight.mean()

然后將其傳入 groupby 中:

In [7]: df.groupby(condition)['Height'].mean()
Out[7]: 
Weight
False    159.034646
True     172.705357
Name: Height, dtype: float64

從索引可以看出,其實(shí)最后產(chǎn)生的結(jié)果就是按照條件列表中元素的值(此處是 True 和 False )來(lái)分組,下面用隨機(jī)傳入字母序列來(lái)驗(yàn)證這一想法:

In [8]: item = np.random.choice(list('abc'), df.shape[0])

In [9]: df.groupby(item)['Height'].mean()
Out[9]: 
a    163.924242
b    162.928814
c    162.708621
Name: Height, dtype: float64

此處的索引就是原先item中的元素,如果傳入多個(gè)序列進(jìn)入 groupby ,那么最后分組的依據(jù)就是這兩個(gè)序列對(duì)應(yīng)行的唯一組合:

In [10]: df.groupby([condition, item])['Height'].mean()
Out[10]: 
Weight   
False   a    160.193617
        b    158.921951
        c    157.756410
True    a    173.152632
        b    172.055556
        c    172.873684
Name: Height, dtype: float64

由此可以看出,之前傳入列名只是一種簡(jiǎn)便的記號(hào),事實(shí)上等價(jià)于傳入的是一個(gè)或多個(gè)列,最后分組的依據(jù)來(lái)自于數(shù)據(jù)來(lái)源組合的unique值,通過(guò) drop_duplicates 就能知道具體的組類別:

In [11]: df[['School', 'Gender']].drop_duplicates()
Out[11]: 
                           School  Gender
0   Shanghai Jiao Tong University  Female
1               Peking University    Male
2   Shanghai Jiao Tong University    Male
3                Fudan University  Female
4                Fudan University    Male
5             Tsinghua University  Female
9               Peking University  Female
16            Tsinghua University    Male

In [12]: df.groupby([df['School'], df['Gender']])['Height'].mean()
Out[12]: 
School                         Gender
Fudan University               Female    158.776923
                               Male      174.212500
Peking University              Female    158.666667
                               Male      172.030000
Shanghai Jiao Tong University  Female    159.122500
                               Male      176.760000
Tsinghua University            Female    159.753333
                               Male      171.638889
Name: Height, dtype: float64
  1. Groupby對(duì)象
    能夠注意到,最終具體做分組操作時(shí),所調(diào)用的方法都來(lái)自于 pandas 中的 groupby 對(duì)象,這個(gè)對(duì)象上定義了許多方法,也具有一些方便的屬性。
In [13]: gb = df.groupby(['School', 'Grade'])

In [14]: gb
Out[14]: <pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000024372714408>

通過(guò) ngroups 屬性,可以得到分組個(gè)數(shù):

In [15]: gb.ngroups
Out[15]: 16

通過(guò) groups 屬性,可以返回從 組名 映射到 組索引列表 的字典:

In [16]: res = gb.groups

In [17]: res.keys() # 字典的值由于是索引,元素個(gè)數(shù)過(guò)多,此處只展示字典的鍵
Out[17]: dict_keys([('Fudan University', 'Freshman'), ('Fudan University', 'Junior'), ('Fudan University', 'Senior'), ('Fudan University', 'Sophomore'), ('Peking University', 'Freshman'), ('Peking University', 'Junior'), ('Peking University', 'Senior'), ('Peking University', 'Sophomore'), ('Shanghai Jiao Tong University', 'Freshman'), ('Shanghai Jiao Tong University', 'Junior'), ('Shanghai Jiao Tong University', 'Senior'), ('Shanghai Jiao Tong University', 'Sophomore'), ('Tsinghua University', 'Freshman'), ('Tsinghua University', 'Junior'), ('Tsinghua University', 'Senior'), ('Tsinghua University', 'Sophomore')])

當(dāng) size 作為 DataFrame 的屬性時(shí),返回的是表長(zhǎng)乘以表寬的大小,但在 groupby 對(duì)象上表示統(tǒng)計(jì)每個(gè)組的元素個(gè)數(shù):

In [18]: gb.size()
Out[18]: 
School                         Grade    
Fudan University               Freshman      9
                               Junior       12
                               Senior       11
                               Sophomore     8
Peking University              Freshman     13
                               Junior        8
                               Senior        8
                               Sophomore     5
Shanghai Jiao Tong University  Freshman     13
                               Junior       17
                               Senior       22
                               Sophomore     5
Tsinghua University            Freshman     17
                               Junior       22
                               Senior       14
                               Sophomore    16
dtype: int64

通過(guò) get_group 方法可以直接獲取所在組對(duì)應(yīng)的行,此時(shí)必須知道組的具體名字:

In [19]: gb.get_group(('Fudan University', 'Freshman')).iloc[:3, :3] # 展示一部分
Out[19]: 
              School     Grade             Name
15  Fudan University  Freshman  Changqiang Yang
28  Fudan University  Freshman     Gaoqiang Qin
63  Fudan University  Freshman     Gaofeng Zhao

這里列出了2個(gè)屬性和2個(gè)方法,而先前的 mean 、 median 都是 groupby 對(duì)象上的方法,這些函數(shù)和許多其他函數(shù)的操作具有高度相似性,將在之后的小節(jié)進(jìn)行專門介紹。

  1. 分組的三大操作
    熟悉了一些分組的基本知識(shí)后,重新回到開(kāi)頭舉的三個(gè)例子,可能會(huì)發(fā)現(xiàn)一些端倪,即這三種類型分組返回的數(shù)據(jù)型態(tài)并不一樣:

    第一個(gè)例子中,每一個(gè)組返回一個(gè)標(biāo)量值,可以是平均值、中位數(shù)、組容量 size 等

    第二個(gè)例子中,做了原序列的標(biāo)準(zhǔn)化處理,也就是說(shuō)每組返回的是一個(gè) Series 類型

    第三個(gè)例子中,既不是標(biāo)量也不是序列,返回的整個(gè)組所在行的本身,即返回了 DataFrame 類型

由此,引申出分組的三大操作:聚合、變換和過(guò)濾,分別對(duì)應(yīng)了三個(gè)例子的操作,下面就要分別介紹相應(yīng)的 agg 、 transform 和 filter 函數(shù)及其操作。
二、聚合函數(shù)

1. 內(nèi)置聚合函數(shù)

在介紹agg之前,首先要了解一些直接定義在groupby對(duì)象的聚合函數(shù),因?yàn)樗乃俣然径紩?huì)經(jīng)過(guò)內(nèi)部的優(yōu)化,使用功能時(shí)應(yīng)當(dāng)優(yōu)先考慮。根據(jù)返回標(biāo)量值的原則,包括如下函數(shù): max/min/mean/median/count/all/any/idxmax/idxmin/mad/nunique/skew/quantile/sum/std/var/sem/size/prod` 。

In [20]: gb = df.groupby('Gender')['Height']

In [21]: gb.idxmin()
Out[21]: 
Gender
Female    143
Male      199
Name: Height, dtype: int64

In [22]: gb.quantile(0.95)
Out[22]: 
Gender
Female    166.8
Male      185.9
Name: Height, dtype: float64

這些聚合函數(shù)當(dāng)傳入的數(shù)據(jù)來(lái)源包含多個(gè)列時(shí),將按照列進(jìn)行迭代計(jì)算:

In [23]: gb = df.groupby('Gender')[['Height', 'Weight']]

In [24]: gb.max()
Out[24]: 
        Height  Weight
Gender                
Female   170.2    63.0
Male     193.9    89.0
  1. agg方法
    雖然在 groupby 對(duì)象上定義了許多方便的函數(shù),但仍然有以下不便之處:

    無(wú)法同時(shí)使用多個(gè)函數(shù)

    無(wú)法對(duì)特定的列使用特定的聚合函數(shù)

    無(wú)法使用自定義的聚合函數(shù)

    無(wú)法直接對(duì)結(jié)果的列名在聚合前進(jìn)行自定義命名

下面說(shuō)明如何通過(guò) agg 函數(shù)解決這四類問(wèn)題:

【a】使用多個(gè)函數(shù)

當(dāng)使用多個(gè)聚合函數(shù)時(shí),需要用列表的形式把內(nèi)置聚合函數(shù)對(duì)應(yīng)的字符串傳入,先前提到的所有字符串都是合法的。

In [25]: gb.agg(['sum', 'idxmax', 'skew'])
Out[25]: 
         Height                   Weight                 
            sum idxmax      skew     sum idxmax      skew
Gender                                                   
Female  21014.0     28 -0.219253  6469.0     28 -0.268482
Male     8854.9    193  0.437535  3929.0      2 -0.332393

從結(jié)果看,此時(shí)的列索引為多級(jí)索引,第一層為數(shù)據(jù)源,第二層為使用的聚合方法,分別逐一對(duì)列使用聚合,因此結(jié)果為6列。

【b】對(duì)特定的列使用特定的聚合函數(shù)

對(duì)于方法和列的特殊對(duì)應(yīng),可以通過(guò)構(gòu)造字典傳入 agg 中實(shí)現(xiàn),其中字典以列名為鍵,以聚合字符串或字符串列表為值。

In [26]: gb.agg({'Height':['mean','max'], 'Weight':'count'})
Out[26]: 
           Height        Weight
             mean    max  count
Gender                         
Female  159.19697  170.2    135
Male    173.62549  193.9     54

【c】使用自定義函數(shù)

在 agg 中可以使用具體的自定義函數(shù), 需要注意傳入函數(shù)的參數(shù)是之前數(shù)據(jù)源中的列,逐列進(jìn)行計(jì)算 。下面分組計(jì)算身高和體重的極差:

In [27]: gb.agg(lambda x: x.mean()-x.min())
Out[27]: 
          Height     Weight
Gender                     
Female  13.79697  13.918519
Male    17.92549  21.759259

由于傳入的是序列,因此序列上的方法和屬性都是可以在函數(shù)中使用的,只需保證返回值是標(biāo)量即可。下面的例子是指,如果組的指標(biāo)均值,超過(guò)該指標(biāo)的總體均值,返回High,否則返回Low。

In [28]: def my_func(s):
   ....:     res = 'High'
   ....:     if s.mean() <= df[s.name].mean():
   ....:         res = 'Low'
   ....:     return res
   ....: 

In [29]: gb.agg(my_func)
Out[29]: 
       Height Weight
Gender              
Female    Low    Low
Male     High   High

【d】聚合結(jié)果重命名

如果想要對(duì)聚合結(jié)果的列名進(jìn)行重命名,只需要將上述函數(shù)的位置改寫成元組,元組的第一個(gè)元素為新的名字,第二個(gè)位置為原來(lái)的函數(shù),包括聚合字符串和自定義函數(shù),現(xiàn)舉若干例子說(shuō)明:

In [30]: gb.agg([('range', lambda x: x.max()-x.min()), ('my_sum', 'sum')])
Out[30]: 
       Height          Weight        
        range   my_sum  range  my_sum
Gender                               
Female   24.8  21014.0   29.0  6469.0
Male     38.2   8854.9   38.0  3929.0
In [31]: gb.agg({'Height': [('my_func', my_func), 'sum'],
   ....:         'Weight': lambda x:x.max()})
   ....: 
Out[31]: 
        Height            Weight
       my_func      sum <lambda>
Gender                          
Female     Low  21014.0     63.0
Male      High   8854.9     89.0

另外需要注意,使用對(duì)一個(gè)或者多個(gè)列使用單個(gè)聚合的時(shí)候,重命名需要加方括號(hào),否則就不知道是新的名字還是手誤輸錯(cuò)的內(nèi)置函數(shù)字符串:

In [32]: gb.agg([('my_sum', 'sum')])
Out[32]: 
         Height  Weight
         my_sum  my_sum
Gender                 
Female  21014.0  6469.0
Male     8854.9  3929.0
In [33]: gb.agg({'Height': [('my_func', my_func), 'sum'],
   ....:         'Weight': [('range', lambda x:x.max())]})
   ....: 
Out[33]: 
        Height          Weight
       my_func      sum  range
Gender                        
Female     Low  21014.0   63.0
Male      High   8854.9   89.0

三、變換和過(guò)濾

1. 變換函數(shù)與transform方法

變換函數(shù)的返回值為同長(zhǎng)度的序列,最常用的內(nèi)置變換函數(shù)是累計(jì)函數(shù): cumcount/cumsum/cumprod/cummax/cummin ,它們的使用方式和聚合函數(shù)類似,只不過(guò)完成的是組內(nèi)累計(jì)操作。此外在 groupby 對(duì)象上還定義了填充類和滑窗類的變換函數(shù).

In [34]: gb.cummax().head()
Out[34]: 
   Height  Weight
0   158.9    46.0
1   166.5    70.0
2   188.9    89.0
3     NaN    46.0
4   188.9    89.0

當(dāng)用自定義變換時(shí)需要使用 transform 方法,被調(diào)用的自定義函數(shù), 其傳入值為數(shù)據(jù)源的序列 ,與 agg 的傳入類型是一致的,其最后的返回結(jié)果是行列索引與數(shù)據(jù)源一致的 DataFrame 。

現(xiàn)對(duì)身高和體重進(jìn)行分組標(biāo)準(zhǔn)化,即減去組均值后除以組的標(biāo)準(zhǔn)差:

In [35]: gb.transform(lambda x: (x-x.mean())/x.std()).head()
Out[35]: 
     Height    Weight
0 -0.058760 -0.354888
1 -1.010925 -0.355000
2  2.167063  2.089498
3       NaN -1.279789
4  0.053133  0.159631

前面提到了 transform 只能返回同長(zhǎng)度的序列,但事實(shí)上還可以返回一個(gè)標(biāo)量,這會(huì)使得結(jié)果被廣播到其所在的整個(gè)組,這種 標(biāo)量廣播 的技巧在特征工程中是非常常見(jiàn)的。例如,構(gòu)造兩列新特征來(lái)分別表示樣本所在性別組的身高均值和體重均值:

In [36]: gb.transform('mean').head() # 傳入返回標(biāo)量的函數(shù)也是可以的
Out[36]: 
      Height     Weight
0  159.19697  47.918519
1  173.62549  72.759259
2  173.62549  72.759259
3  159.19697  47.918519
4  173.62549  72.759259
  1. 組索引與過(guò)濾
    在上一章中介紹了索引的用法,那么索引和過(guò)濾有什么區(qū)別呢?

過(guò)濾在分組中是對(duì)于組的過(guò)濾,而索引是對(duì)于行的過(guò)濾,在第二章中的返回值,無(wú)論是布爾列表還是元素列表或者位置列表,本質(zhì)上都是對(duì)于行的篩選,即如果符合篩選條件的則選入結(jié)果表,否則不選入。

組過(guò)濾作為行過(guò)濾的推廣,指的是如果對(duì)一個(gè)組的全體所在行進(jìn)行統(tǒng)計(jì)的結(jié)果返回 True 則會(huì)被保留, False 則該組會(huì)被過(guò)濾,最后把所有未被過(guò)濾的組其對(duì)應(yīng)的所在行拼接起來(lái)作為 DataFrame 返回。

在 groupby 對(duì)象中,定義了 filter 方法進(jìn)行組的篩選,其中自定義函數(shù)的輸入?yún)?shù)為數(shù)據(jù)源構(gòu)成的 DataFrame 本身,在之前例子中定義的 groupby 對(duì)象中,傳入的就是 df[['Height', 'Weight']] ,因此所有表方法和屬性都可以在自定義函數(shù)中相應(yīng)地使用,同時(shí)只需保證自定義函數(shù)的返回為布爾值即可。

例如,在原表中通過(guò)過(guò)濾得到所有容量大于100的組:

In [37]: gb.filter(lambda x: x.shape[0] > 100).head()
Out[37]: 
   Height  Weight
0   158.9    46.0
3     NaN    41.0
5   158.0    51.0
6   162.5    52.0
7   161.9    50.0

四、跨列分組

  1. apply的引入
    之前幾節(jié)介紹了三大分組操作,但事實(shí)上還有一種常見(jiàn)的分組場(chǎng)景,無(wú)法用前面介紹的任何一種方法處理,例如現(xiàn)在如下定義身體質(zhì)量指數(shù)BMI:
    BMI=Weight/Height**2
    其中體重和身高的單位分別為千克和米,需要分組計(jì)算組BMI的均值。

首先,這顯然不是過(guò)濾操作,因此 filter 不符合要求;其次,返回的均值是標(biāo)量而不是序列,因此 transform 不符合要求;最后,似乎使用 agg 函數(shù)能夠處理,但是之前強(qiáng)調(diào)過(guò)聚合函數(shù)是逐列處理的,而不能夠 多列數(shù)據(jù)同時(shí)處理 。由此,引出了 apply 函數(shù)來(lái)解決這一問(wèn)題。

  1. apply的使用
    在設(shè)計(jì)上, apply 的自定義函數(shù)傳入?yún)?shù)與 filter 完全一致,只不過(guò)后者只允許返回布爾值?,F(xiàn)如下解決上述計(jì)算問(wèn)題:
In [38]: def BMI(x):
   ....:     Height = x['Height']/100
   ....:     Weight = x['Weight']
   ....:     BMI_value = Weight/Height**2
   ....:     return BMI_value.mean()
   ....: 

In [39]: gb.apply(BMI)
Out[39]: 
Gender
Female    18.860930
Male      24.318654
dtype: float64

除了返回標(biāo)量之外, apply 方法還可以返回一維 Series 和二維 DataFrame ,但它們產(chǎn)生的數(shù)據(jù)框維數(shù)和多級(jí)索引的層數(shù)應(yīng)當(dāng)如何變化?下面舉三組例子就非常容易明白結(jié)果是如何生成的:

【a】標(biāo)量情況:結(jié)果得到的是 Series ,索引與 agg 的結(jié)果一致

In [40]: gb = df.groupby(['Gender','Test_Number'])[['Height','Weight']]

In [41]: gb.apply(lambda x: 0)
Out[41]: 
Gender  Test_Number
Female  1              0
        2              0
        3              0
Male    1              0
        2              0
        3              0
dtype: int64

In [42]: gb.apply(lambda x: [0, 0]) # 雖然是列表,但是作為返回值仍然看作標(biāo)量
Out[42]: 
Gender  Test_Number
Female  1              [0, 0]
        2              [0, 0]
        3              [0, 0]
Male    1              [0, 0]
        2              [0, 0]
        3              [0, 0]
dtype: object

【b】 Series 情況:得到的是 DataFrame ,行索引與標(biāo)量情況一致,列索引為 Series 的索引

In [43]: gb.apply(lambda x: pd.Series([0,0],index=['a','b']))
Out[43]: 
                    a  b
Gender Test_Number      
Female 1            0  0
       2            0  0
       3            0  0
Male   1            0  0
       2            0  0
       3            0  0

【c】 DataFrame 情況:得到的是 DataFrame ,行索引最內(nèi)層在每個(gè)組原先 agg 的結(jié)果索引上,再加一層返回的 DataFrame 行索引,同時(shí)分組結(jié)果 DataFrame 的列索引和返回的 DataFrame 列索引一致。

In [44]: gb.apply(lambda x: pd.DataFrame(np.ones((2,2)),
   ....:                                 index = ['a','b'],
   ....:                                 columns=pd.Index([('w','x'),('y','z')])))
   ....: 
Out[44]: 
                        w    y
                        x    z
Gender Test_Number            
Female 1           a  1.0  1.0
                   b  1.0  1.0
       2           a  1.0  1.0
                   b  1.0  1.0
       3           a  1.0  1.0
                   b  1.0  1.0
Male   1           a  1.0  1.0
                   b  1.0  1.0
       2           a  1.0  1.0
                   b  1.0  1.0
       3           a  1.0  1.0
                   b  1.0  1.0

最后需要強(qiáng)調(diào)的是, apply 函數(shù)的靈活性是以犧牲一定性能為代價(jià)換得的,除非需要使用跨列處理的分組處理,否則應(yīng)當(dāng)使用其他專門設(shè)計(jì)的 groupby 對(duì)象方法,否則在性能上會(huì)存在較大的差距。同時(shí),在使用聚合函數(shù)和變換函數(shù)時(shí),也應(yīng)當(dāng)優(yōu)先使用內(nèi)置函數(shù),它們經(jīng)過(guò)了高度的性能優(yōu)化,一般而言在速度上都會(huì)快于用自定義函數(shù)來(lái)實(shí)現(xiàn)。

五.總結(jié)
這章屬于重點(diǎn)章節(jié),分組聚合在工程中運(yùn)用甚廣,做挖掘的時(shí)候常常用到這部分內(nèi)容,學(xué)習(xí)之前,一直認(rèn)為agg只能對(duì)python的某些內(nèi)置函數(shù)進(jìn)行聚合,分不清transform和apply的一些區(qū)別,apply比transform來(lái)說(shuō)更加靈活,而且在面對(duì)復(fù)雜計(jì)算的時(shí)候,我們可以考慮使用apply和transform結(jié)合的方法來(lái)做,這樣做的效率也比單一使用的時(shí)候大大提升了。再說(shuō)一下在之前的學(xué)習(xí)中用分組聚合遇到的坑,其中一個(gè)是對(duì)某一列進(jìn)行分組聚合的時(shí)候,由于我要對(duì)這一列進(jìn)行歸一化處理,所以我之前錯(cuò)誤的寫法是

df['b'].apply(lambda x:(x-x.min())/(x.max()-x.min()))

而正確的寫法是:

df[['b']].apply(lambda x:(x-x.min())/(x.max()-x.min()))

倆者的區(qū)別是前一種寫法是值的計(jì)算,而后一種寫法是列的計(jì)算,這里是初學(xué)者特別容易犯的錯(cuò)誤,需要注意。
還有reset_index()的使用,比如什么時(shí)候應(yīng)該指定drop=True,而什么時(shí)候不需要指定。
比如:

df.groupby('a').apply(lambda x:test(x)).reset_index(drop=True)

def test(df):
  return df[:-1]

這種情況就需要指定drop=True,個(gè)人理解是分組切的時(shí)候沒(méi)有改變?cè)瓉?lái)相對(duì)的索引,所以需要將分組之后的相對(duì)索引干掉。
而這種情況則不需要去掉:

df.groupby('a')[['b','c']].count().reset_index()

這種情況沒(méi)有保留原來(lái)的相對(duì)索引,而是把分組的那一列作為了新索引,如果我們?cè)趓eset_index()的時(shí)候指定drop=True,那么就會(huì)刪除這一列。
坑就先說(shuō)到這里,還有一些小坑就不再這里列舉了,希望大家平時(shí)勤做筆記,將遇到的問(wèn)題記錄下來(lái),方便之后遇到同樣的問(wèn)題,不需要再耗費(fèi)大量的時(shí)間,最后祝大家節(jié)日快樂(lè)!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容