pandas系列(三)Pandas分組

2020-12-27 酷扯兒

本文轉載自【微信公眾號:五角錢的程式設計師,ID:xianglin965】經微信公眾號授權轉載,如需轉載與原文作者聯繫

文章目錄

第3章 分組一、SAC過程1. 內涵2. apply過程二、groupby函數1. 分組函數的基本內容:2. groupby對象的特點三、聚合、過濾和變換1. 聚合(Aggregation)2. 過濾(Filteration)3. 變換(Transformation)四、apply函數1. apply函數的靈活性2. 用apply同時統計多個指標

第3章 分組

import numpy as np

import pandas as pd

df = pd.read_csv('data/table.csv',index_col='ID')

df

一、SAC過程

1. 內涵

1.SAC指的是分組操作中的split-apply-combine過程

2.其中split指基於某一些規則,將數據拆成若干組,apply是指對每一組獨立地使用函

數,combine指將每一組的結果組合成某一類數據結構

2. apply過程

在該過程中,我們實際往往會遇到四類問題:

1.整合(Aggregation)——即分組計算統計量(如求均值、求每組元素個數)

2.變換(Transformation)——即分組對每個單元的數據進行操作(如元素標準化)

3.過濾(Filtration)——即按照某些規則篩選出一些組(如選出組內某一指標小於50的組)

綜合問題——即前面提及的三種問題的混合

二、groupby函數

1. 分組函數的基本內容:

(a)根據某一列分組

grouped_single = df.groupby('School')

經過groupby後會生成一個groupby對象,該對象本身不會返回任何東西,只有當相應的方法被調用才會起作用

例如取出某一個組:

grouped_single.get_group('S_2').head()

(b)根據某幾列分組

grouped_mul = df.groupby(['School','Class'])

grouped_mul.get_group(('S_1','C_3'))

(c)組容量與組數

grouped_single.size()

grouped_mul.size()

grouped_single.ngroups

grouped_mul.ngroups

(d)組的遍歷

for name,group in grouped_single:

print(name)

display(group.head())

(e)level參數(用於多級索引)和axis參數

df.set_index(['Gender','School']).groupby(level=1,axis=0).get_group('S_1')

2. groupby對象的特點

(a)查看所有可調用的方法

由此可見,groupby對象可以使用相當多的函數,靈活程度很高

print([attr for attr in dir(grouped_single) if not attr.startswith('_')])

(b)分組對象的head和first

對分組對象使用head函數,返回的是每個組的前幾行,而不是數據集前幾行

grouped_single.head(3)

first顯示的是以分組為索引的每組的第一個分組信息

grouped_single.first()

(c)分組依據

對於groupby函數而言,分組的依據是非常自由的,只要是與數據框長度相同的列表即可,同時支持函數型分組

np.random.choice(['a','b','c'],df.shape[0])

df.groupby(np.random.choice(['a','b','c'],df.shape[0])).get_group('b').head()

#相當於將np.random.choice(['a','b','c'],df.shape[0])當做新的一列進行分組

從原理上說,我們可以看到利用函數時,傳入的對象就是索引,因此根據這一特性可以做一些複雜的操作

df[:5].groupby(lambda x:print(x)).head(0)

根據奇偶行分組

df.groupby(lambda x:'奇數行' if not df.index.get_loc(x)%2==1 else '偶數行').groups

如果是多層索引,那麼lambda表達式中的輸入就是元組,下面實現的功能為查看兩所學校中男女生分別均分是否及格

注意:此處只是演示groupby的用法,實際操作不會這樣寫

math_score = df.set_index(['Gender','School'])['Math'].sort_index()

grouped_score = df.set_index(['Gender','School']).sort_index().groupby(lambda x:(x,'均分及格' if math_score[x].mean()>=60 else '均分不及格'))

for name,_ in grouped_score:

print(name)

(d)groupby的[]操作

可以用[]選出groupby對象的某個或者某幾個列,上面的均分比較可以如下簡潔地寫出:

df.groupby(['Gender','School'])['Math'].mean()>=60

用列表可選出多個屬性列:

df.groupby(['Gender','School'])[['Math','Height']].mean()

(e)連續型變量分組

例如利用cut函數對數學成績分組:

bins = [0,40,60,80,90,100]

cuts = pd.cut(df['Math'],bins=bins) #可選label添加自定義標籤

df.groupby(cuts)['Math'].count()

三、聚合、過濾和變換

1. 聚合(Aggregation)

(a)常用聚合函數

所謂聚合就是把一堆數,變成一個標量,因此mean/sum/size/count/std/var/sem/describe/first/last/nth/min/max都是聚合函數

為了熟悉操作,不妨驗證標準誤sem函數,它的計算公式是:\frac{組內標準差}{\sqrt{組容量}}組容量組內標準差,下面進行驗證:

group_m = grouped_single['Math']

group_m.std().values/np.sqrt(group_m.count().values)== group_m.sem().values

(b)同時使用多個聚合函數

group_m.agg(['sum','mean','std'])

利用元組進行重命名

group_m.agg([('rename_sum','sum'),('rename_mean','mean')])

指定哪些函數作用哪些列

grouped_mul.agg({'Math':['mean','max'],'Height':'var'})

(c)使用自定義函數

grouped_single['Math'].agg(lambda x:print(x.head(),'間隔'))

#可以發現,agg函數的傳入是分組逐列進行的,有了這個特性就可以做許多事情

官方沒有提供極差計算的函數,但通過agg可以容易地實現組內極差計算

grouped_single['Math'].agg(lambda x:x.max()-x.min())

(d)利用NamedAgg函數進行多個聚合

注意:不支持lambda函數,但是可以使用外置的def函數

def R1(x):

return x.max()-x.min()

def R2(x):

return x.max()-x.median()

grouped_single['Math'].agg(min_score1=pd.NamedAgg(column='col1', aggfunc=R1),

max_score1=pd.NamedAgg(column='col2', aggfunc='max'),

range_score2=pd.NamedAgg(column='col3', aggfunc=R2)).head()

(e)帶參數的聚合函數

判斷是否組內數學分數至少有一個值在50-52之間:

def f(s,low,high):

return s.between(low,high).max()

grouped_single['Math'].agg(f,50,52)

如果需要使用多個函數,並且其中至少有一個帶參數,則使用wrap技巧:

def f_test(s,low,high):

return s.between(low,high).max()

def agg_f(f_mul,name,*args,**kwargs):

def wrapper(x):

return f_mul(x,*args,**kwargs)

wrapper.__name__ = name

return wrapper

new_f = agg_f(f_test,'at_least_one_in_50_52',50,52)

grouped_single['Math'].agg([new_f,'mean']).head()

2. 過濾(Filteration)

filter函數是用來篩選某些組的(務必記住結果是組的全體),因此傳入的值應當是布爾標量

grouped_single[['Math','Physics']].filter(lambda x:(x['Math']>32).all()).head()

3. 變換(Transformation)

(a)傳入對象

transform函數中傳入的對象是組內的列,並且返回值需要與列長完全一致

grouped_single[['Math','Height']].transform(lambda x:x-x.min()).head()

如果返回了標量值,那麼組內的所有元素會被廣播為這個值

grouped_single[['Math','Height']].transform(lambda x:x.mean()).head()

(b)利用變換方法進行組內標準化

grouped_single[['Math','Height']].transform(lambda x:(x-x.mean())/x.std()).head()

(c)利用變換方法進行組內缺失值的均值填充

df_nan = df[['Math','School']].copy().reset_index()

df_nan.loc[np.random.randint(0,df.shape[0],25),['Math']]=np.nan

df_nan.head()

df_nan.groupby('School').transform(lambda x: x.fillna(x.mean())).join(df.reset_index()['School']).head()

四、apply函數

1. apply函數的靈活性

可能在所有的分組函數中,apply是應用最為廣泛的,這得益於它的靈活性:

對於傳入值而言,從下面的列印內容可以看到是以分組的表傳入apply中:

df.groupby('School').apply(lambda x:print(x.head(1)))

apply函數的靈活性很大程度來源於其返回值的多樣性:

① 標量返回值

df[['School','Math','Height']].groupby('School').apply(lambda x:x.max())

② 列表返回值

df[['School','Math','Height']].groupby('School').apply(lambda x:x-x.min()).head()

③ 數據框返回值

df[['School','Math','Height']].groupby('School')\

.apply(lambda x:pd.DataFrame({'col1':x['Math']-x['Math'].max(),

'col2':x['Math']-x['Math'].min(),

'col3':x['Height']-x['Height'].max(),

'col4':x['Height']-x['Height'].min()})).head()

2. 用apply同時統計多個指標

此處可以藉助OrderedDict工具進行快捷的統計:

from collections import OrderedDict

def f(df):

data = OrderedDict()

data['M_sum'] = df['Math'].sum()

data['W_var'] = df['Weight'].var()

data['H_mean'] = df['Height'].mean()

return pd.Series(data)

grouped_single.apply(f)

相關焦點

  • 對比MySQL學習Pandas的groupby分組聚合
    然後就是執行where篩選,對比pandas就相當於寫一個condition1過濾條件,做一個分組前的篩選篩選。接著就是執行group分組條件,對比pandas就是寫一個groupby條件進行分組。最後執行的是having表示分組後的篩選,在pandas中,通過上圖可以發現我們得到了一個df1對象,針對這個df1對象,我們再做一次篩選,也表示分組後的篩選。
  • 十分鐘學習pandas!pandas常用操作總結!
    學習Python, 當然少不了pandas,pandas是python數據科學中的必備工具,熟練使用pandas是從sql boy/girl 跨越到一名優秀的數據分析師傅的必備技能。這篇pandas常用操作總結幫大家回顧下pandas的常用語法,尤其是我們分析數據時常用的方法。
  • 一場pandas與SQL的巔峰大戰(七)
    pandas操作MySQL資料庫    read_sql    to_sql巔峰系列總結十條(驚喜在此)reference 在之前的六篇系列文章中,我們對比了pandas和SQL在數據方面的多項操作。
  • 「Python替代Excel Vba」系列(二):pandas分組統計與操作Excel
    請關注本號,更多乾貨,立刻送達~~系列列錶帶你用pandas玩轉各種數據處理前言在本系列的上一章已經介紹了如何讀寫 excel 數據,並快速進行匯總處理。但有些小夥伴看完之後有些疑惑:那只是簡單讀寫數據而已,有時候需要設置 excel 的格式。
  • 十分鐘學習pandas! pandas常用操作總結!
    學習Python, 當然少不了pandas,pandas是python數據科學中的必備工具
  • pandas使用的100個trick
    pandas是處理數據的必備工具,可以方便地篩選,統計,分組集計,轉換等操作,而且pandas(熊貓)這麼可愛,誰能不愛呢但是如果你對pandas說No,參考以下視頻100個trick•Trick 1: 一行查看數據總體情況•Trick 2: pd.read_csv()中有用的參數•Trick 3: datetime對象可用接口•Trick 4: 將小類別統一划分為一類•Trick 5: 用多個篩選條件篩選數據的清爽寫法•Trick 6: 把連續變量分組(cut )•Trick 7: 將集計過的結果與原數據合併•Trick 8: groupby後獲得某分組
  • 掌握pandas中的transform
    本文就將帶大家掌握pandas中關於transform的一些常用使用方式。圖12 pandas中的transform在pandas中transform根據作用對象和場景的不同,主要可分為以下幾種:2.1 transform作用於Series當transform作用於單列Series時較為簡單,以前段時間非常流行的「企鵝數據集」
  • Pandas數據清洗系列:read_csv函數詳解(三)
    接上一篇文章:Pandas數據清洗系列:read_csv函數詳解(二)我們學習read_csv函數中剩下的參數。為了演示這個參數,我們給數據增加三列數據year、month、day。keep_date_col上面的例子上,我們將year、month、day三個列組合成一個新的日期時間列date,但是原來的year、month和day被刪去了,如果將keep_date_col設置為True,可以保留這三個列。
  • 【數據分析】Pandas
    其他常用方法                ✦ ✦ ✦ ✦ ✦ ✦1、簡介pandas是一個強大的Python數據分析的工具包,它是基於Numpy構建的,正因pandas的出現pandas對象(無論Series、DataFrame還是其他的什麼)當中的數據會根據提供的一個或者多個鍵被拆分為多組,拆分操作實在對象的特定軸上執行的。
  • Pandas與Excel徹底拉開了距離.....
    通過Pandas我們可以方便的操作數據的增、查、改、刪、合併、重塑、分組、統計分析,此外Pandas還提供了非常成熟的I/O工具,用於讀取文本文件,excel文件,資料庫等不同來源數據,利用超快的HDF5格式保存/加載數據。
  • 一場pandas與SQL的巔峰大戰(二)
    pandas和SQL代碼如下所示,注意使用like時,%是通配符,表示匹配任意長度的字符。>圖片中代碼:#pythonorder['dt4'] = order['ts'].astype(str).str.replace('-', '')order.head()#Hive SQLselect *, regexp_replace(ts, '-', '') as dt4from t_order;三、
  • pandas指南:做更高效的數據科學家
    今天我要告訴你們的是:在數據科學中,有一個軟體包是你們絕對需要學習的,那就是pandas。而pandas真正有趣的地方是,很多其他的包也在裡面。pandas是一個核心包,因此它具有來自其他各種包的特性。
  • Pandas的crosstab函數
    在更複雜的數據科學環境中,這些複雜函數的好處更為明顯,並且經常被更有經驗的pandas用戶使用。在這篇文章中,我將教你如何使用crosstab以及如何在其他類似函數中選擇它。                cmap='rocket_r',                linewidths=.5,                ax=ax)    plt.show();Pandas crosstab()與pivot_table()和groupby()的比較在我們繼續討論更有趣的內容之前,我想我需要澄清計算分組摘要統計的三個函數之間的區別
  • Pandas的介紹與基本使用
    以上就是pandas能完成的一些基礎操作,當然並不完全,下面就來看看pandas到底是怎麼用的。3.4.1、分組(GroupBY機制)pandas對象(無論Series、DataFrame還是其他的什麼)當中的數據會根據提供的一個或者多個鍵被拆分為多組,拆分操作實在對象的特定軸上執行的。就比如DataFrame可以在他的行上或者列上進行分組,然後將一個函數應用到各個分組上並產生一個新的值。最後將所有的執行結果合併到最終的結果對象中。
  • 「Python替代Excel Vba」系列(三):pandas處理不規範數據
    系列文章帶你用pandas玩轉各種數據處理「Python替代Excel Vba」系列(二):pandas分組統計與操作Excel前言本系列前2篇已經稍微展示了 python 在數據處理方面的強大能力,這主要得益於 pandas 包的各種靈活處理方式。
  • 超全的pandas數據分析常用函數總結:下篇
    'money']>=10, 'high', 'low')data輸出結果:5.5更多關於pandas.DataFrame.loc的用法,戳下面官方連結:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.loc.html#pandas.DataFrame.loc
  • 數據分析之Pandas變形操作總結
    Pandas做分析數據,可以分為索引、分組、變形及合併四種操作。前邊已經介紹過索引操作、分組操作,現在接著對Pandas中的變形操作進行介紹,涉及知識點提綱如下圖:     本文目錄              1.
  • 懶人秘籍:教你如何避免編寫pandas代碼
    開始pandas遊戲之旅,請閱讀如下資源:5個鮮為人知的pandas技巧使用pandas進行探索性數據分析數據集有三列:id表示唯一的標識city表示預定的城市信息booked perc表示特定時間預定的百分比數據集有一萬條,這使速度改進更加明顯。注意,如果代碼以正確的pandas方式編寫,pandas可以利用DataFrames計算數百萬(甚至數十億)行的統計數據。
  • Pandas系列 - 基本數據結構
    二、pandas.DataFrame數據幀(DataFrame)是二維數據結構,即數據以行和列的表格方式排列數據幀(DataFrame)的功能特點:構造函數:pandas.DataFrame(data,
  • 如何通過一頓飯來說明NumPy與pandas的功用
    而在這股勢力中,其主角及成員便是NumPy、pandas、matplotlib以及scipy。本文要簡單介紹的則是主力中的主力:NumPy與pandas。誠然,R語言幾乎專注於統計分析,其第三方包無數,有著統計學的深度以及各學科統計分析應用的廣度,並且也在與Python的較量中不甘示弱。