第四章 分組

全文知識(shí)架構(gòu)

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

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

【練一練】

請(qǐng)根據(jù)上下四分位數(shù)分割,將體重分為high、normal、low三組,統(tǒng)計(jì)身高的均值。

high = df['Weight'].quantile(0.75)
low = df['Weight'].quantile(0.25)
level = df['Weight'].mask(df['Weight']>high, 'high').mask(df['Weight']<low, 'low').mask((low<=df['Weight'])&(df['Weight']<=high), 'normal')
df.groupby(level)['Weight'].mean()

【練一練】

上一小節(jié)介紹了可以通過drop_duplicates得到具體的組類別,現(xiàn)請(qǐng)用groups屬性完成類似的功能。

gb = df.groupby(['School', 'Gender'])
gb.groups.keys()

聚合函數(shù)

聚合函數(shù)

【練一練】

請(qǐng)查閱文檔,明確all/any/mad/skew/sem/prod函數(shù)的含義。

  • all 返回所有的值是否為真的結(jié)果
  • any 返回所有值中是否有真值的結(jié)果
  • mad 根據(jù)平均值計(jì)算絕對(duì)距離差
  • skew 偏度(skewness),是統(tǒng)計(jì)數(shù)據(jù)分布偏斜方向和程度的度量
  • sem 返回所請(qǐng)求軸上的平均值的無偏標(biāo)準(zhǔn)誤差
  • prod 累乘

【練一練】

請(qǐng)使用【b】中的傳入字典的方法完成【a】中等價(jià)的聚合任務(wù)。

gb.agg({'Height':['sum', 'idxmax', 'skew'], 'Weight':['sum', 'idxmax', 'skew']})

【練一練】

groupby對(duì)象中可以使用describe方法進(jìn)行統(tǒng)計(jì)信息匯總,請(qǐng)同時(shí)使用多個(gè)聚合函數(shù),完成與該方法相同的功能。

# 本來想使用傳入函數(shù)列表的方法,發(fā)現(xiàn)通過函數(shù)列表方法不支持給函數(shù)傳入?yún)?shù)
gb.agg([('count',lambda x: x.count()), ('mean', lambda x: x.mean()), ('std', lambda x: x.std()), ('min', lambda x: x.min()), ('25%',lambda x: x.quantile(0.25)),
        ('50%',lambda x: x.quantile(0.5)),('75%',lambda x: x.quantile(0.75))])

變換和過濾

變換和過濾

【練一練】

groupby對(duì)象中,rank方法也是一個(gè)實(shí)用的變換函數(shù),請(qǐng)查閱它的功能并給出一個(gè)使用的例子。

# 這個(gè)操作 是 對(duì)DataFrame某列的數(shù)據(jù)進(jìn)行聚類 然后對(duì)其它列的屬于同類數(shù)據(jù)進(jìn)行數(shù)值大小排序
gb.rank(method='min', ascending=True) # method可以指定max或min,ascending可指定True or False

【練一練】

對(duì)于transform方法無法像agg一樣,通過傳入字典來對(duì)指定列使用特定的變換,如果需要在一次transform的調(diào)用中實(shí)現(xiàn)這種功能,請(qǐng)給出解決方案。

func_dict = {'Height':'max', 'Weight':'min'}
def my_transform(s, transform_dict=func_dict):
    name = s.name
    for key, func in transform_dict.items():
        if key in [name]:
            function = getattr(s, func)
            return function()
gb.transform(my_transform)

跨列分組

跨列分組

【練一練】

請(qǐng)嘗試在apply傳入的自定義函數(shù)中,根據(jù)組的某些特征返回相同長度但索引不同的Series,會(huì)報(bào)錯(cuò)嗎?

def test_func(x):
    if x['Weight'].shape[0] > 10:
        return pd.Series([1,1],index=['a123','b12312'])
    else:
        return pd.Series([0,0],index=['c123123','12312d'])
gb.apply(test_func)
# 會(huì)報(bào)錯(cuò)

【練一練】

請(qǐng)嘗試在apply傳入的自定義函數(shù)中,根據(jù)組的某些特征返回相同大小但列索引不同的DataFrame,會(huì)報(bào)錯(cuò)嗎?如果只是行索引不同,會(huì)報(bào)錯(cuò)嗎?

def test_func(x):
    if x['Weight'].shape[0] > 10:
        return pd.DataFrame(np.ones((2,2)), index = ['a','b'], columns=pd.Index([('w','x'),('y','z')]))
    else:
        return pd.DataFrame(np.ones((2,2)), index = ['c','d'], columns=pd.Index([('w','d'),('y','z')]))
gb.apply(test_func)
# 以上兩種情況都不會(huì)報(bào)錯(cuò)

五、練習(xí)

Ex1:公司員工數(shù)據(jù)集

現(xiàn)有一份公司員工數(shù)據(jù)集:

  1. 分別只使用queryloc選出年齡不超過四十歲且工作部門為DairyBakery的男性。
  2. 選出員工ID號(hào) 為奇數(shù)所在行的第1、第3和倒數(shù)第2列。
  3. 按照以下步驟進(jìn)行索引操作:
  • 把后三列設(shè)為索引后交換內(nèi)外兩層
  • 恢復(fù)中間一層
  • 修改外層索引名為Gender
  • 用下劃線合并兩層行索引
  • 把行索引拆分為原狀態(tài)
  • 修改索引名為原表名稱
  • 恢復(fù)默認(rèn)索引并將列保持為原表的相對(duì)位置
# 問題1
dpt = ['Dairy', 'Bakery']
df.loc[(df.age<=40)&df.department.isin(dpt)&(df.gender=='M')].head(3)
# 問題2
df.iloc[(df.EmployeeID%2==1).values,[0,2,-2]].head()
# 問題三
# 把后三列設(shè)為索引
df_ = df.set_index(['department', 'job_title', 'gender'])
# 交換內(nèi)外兩層
df_ = df_.swaplevel(0,2, axis=0)
# 恢復(fù)中間一層
df_ = df_.reset_index(level=1, drop=False)
# 把外層索引名改為Gender
df_.rename_axis(index={'gender':'Gender'})
# 用下劃線合并兩層索引
df_.index = df_.index.map(lambda x:'_'.join(x))
# 拆分為原狀態(tài)
df_.index = df_.index.map(lambda x:tuple(x.split('_')))
# 修改索引名為原表名稱
df_ = df_.rename_axis(index=['gender','department'])
# 恢復(fù)默認(rèn)
df_ = df_.reset_index().reindex(df.columns, axis=1)
?著作權(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),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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