pandas系列(三)Pandas分組

2021-01-10 酷扯兒

本文轉載自【微信公眾號:五角錢的程式設計師,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)

相關焦點

  • pandas庫中最重要的幾個知識點
    前言本篇是【機器學習與數據挖掘】頭條號原創首發Python數據分析系列文章的第四篇Python數據分析系列文章之Python基礎篇Python數據分析系列文章之NumpyPython數據分析系列文章之Pandas(上)Python數據分析系列文章之Pandas(下)Python數據分析系列文章之ScipyPython數據分析系列文章之MatplotlibPython
  • Pandas的介紹與基本使用
    3.4.1、分組(GroupBY機制)pandas對象(無論Series、DataFrame還是其他的什麼)當中的數據會根據提供的一個或者多個鍵被拆分為多組,拆分操作實在對象的特定軸上執行的。就比如DataFrame可以在他的行上或者列上進行分組,然後將一個函數應用到各個分組上並產生一個新的值。最後將所有的執行結果合併到最終的結果對象中。
  • pandas指南:做更高效的數據科學家
    今天我要告訴你們的是:在數據科學中,有一個軟體包是你們絕對需要學習的,那就是pandas。而pandas真正有趣的地方是,很多其他的包也在裡面。pandas是一個核心包,因此它具有來自其他各種包的特性。pandas類似於Python中的Excel:它使用表(即DataFrame)並對數據進行轉換,但它還能做更多。
  • 懶人秘籍:教你如何避免編寫pandas代碼
    開始pandas遊戲之旅,請閱讀如下資源:5個鮮為人知的pandas技巧使用pandas進行探索性數據分析數據集有三列:id表示唯一的標識city表示預定的城市信息booked perc表示特定時間預定的百分比數據集有一萬條,這使速度改進更加明顯。注意,如果代碼以正確的pandas方式編寫,pandas可以利用DataFrames計算數百萬(甚至數十億)行的統計數據。
  • 如何通過一頓飯來說明NumPy與pandas的功用
    而在這股勢力中,其主角及成員便是NumPy、pandas、matplotlib以及scipy。本文要簡單介紹的則是主力中的主力:NumPy與pandas。誠然,R語言幾乎專注於統計分析,其第三方包無數,有著統計學的深度以及各學科統計分析應用的廣度,並且也在與Python的較量中不甘示弱。
  • Python數據分析:pandas讀取和寫入數據
    繼續深入學習pandas相關操作,數據讀取寫入、分組、合併,轉換等等。前面一篇文章裡已經寫了關於描述性統計以及常用的基本操作。接下來的一段時間裡,我將陸續地去掌握並輸出。這篇文章是關於數據讀取與寫入的知識點。平時工作中,我們會接觸到不同的數據文件,比如很常見的excel文件(後綴名為xls和xlsx),csv、txt等文本文件,json文件以及sql文件等等。
  • 6個提升效率的pandas小技巧
    pandas是python中常用的數據分析庫,出現頻率非常高,而且pandas功能之多讓人咋舌,即使pandas老手也沒法保證能高效使用pandas做數據分析。這篇文章目的梳理幾個高效實用的pandas小技巧,供大家參考。1.
  • PANDAS: 新手教程 一
    # 如果你使用的是Anacondaconda install -c conda-forge pandas# 使用pip安裝Pandaspip install pandas# 導入pandasimport pandas as pd在這個練習中,我將使用著名的鐵達尼號數據集。
  • pandas基礎教程2
    選擇數據:我們在前面說pandas就像字典一樣,字典是可以通過鍵去選擇數據,同樣的pandas也是可以得,且pandas更強。DataFrame中的數據有兩個選取方式,df['A']或者df.A都可以,具體使用什麼方式看你的心情。
  • Python學習120課 pandas簡介kaggle下載數據及pandas讀取外部數據
    現在我們開始學習pandas,pandas一般用的更多,pandas是基於numpy去寫的。pandas是一個專門做數據結構和數據分析的庫。●pandas的安裝推薦使用anaconda,只要安裝了anaconda,它裡面就會自帶pandas,這會為我們省去很多的麻煩。接下來就是用pandas去處理數據,數據從哪來呢?
  • 【跟著stackoverflow學Pandas】- Pandas修改列的類型
    Pandas: change data type of columns - Pandas修改列的類型我們利用pandas進行數據處理經常會遇到數據類型不符的問題
  • pandas基礎教程1
    Pandas是基於Numpy構建的(不知道pandas和我們的國寶有什麼關係),而Numpy和Pandas的數據類型是在基礎數據類型上建立,彼此相關,又彼此不同。Numpy對象最重要特點向量化運算,pandas對象最重要特點是字典和列表混合。
  • 超全的pandas數據分析常用函數總結(下篇)
    上篇文章中,小編給大家總結了數據分析中pandas這一模塊裡面常用函數的四個部分的內容,分別為導入模塊、創建數據集並讀取、數據查看與數據清洗,現在給大家介紹下篇的內容。來源 | 凹凸數據5.輸出結果:5.4 分類顯示如果money列的值>=10, level列顯示high,否則顯示low:data['level'] = np.where(data['money']>=10, 'high', 'low')data輸出結果:5.5 分組標記data.loc[(data['level
  • 從小白到大師,這裡有一份Pandas入門指南
    memory_usage():https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.memory_usage.html了解列的類型(https://pandas.pydata.org/pandas-docs/stable/getting_started/basics.html
  • 不會Pandas怎麼行
    有一個用於數據科學的包絕對是必需的,它就是 pandas。pandas 最有趣的地方在於裡面隱藏了很多包。它是一個核心包,裡面有很多其他包的功能。這點很棒,因為你只需要使用 pandas 就可以完成工作。
  • 懂Excel輕鬆入門Python數據分析包pandas(二十一):透視表
    此系列文章收錄在公眾號中:數據大宇宙 > 數據處理 >E-pd經常聽別人說 Python 在數據領域有多厲害,結果學了很長時間,連數據處理都麻煩得要死。後來才發現,原來不是 Python 數據處理厲害,而是他有數據分析神器—— pandas前言本系列上一節文章最後我隨手使用了 pandas 中的透視表操作,之後有些小夥伴詢問我相關的問題。正好 pandas 的 pivot_table 也是與 Excel 透視表對應。本文簡單教你入門使用 pandas 完成透視表功能。
  • PandaSQL:一個讓你能夠通過SQL語句進行pandas的操作的python包
    它允許切片、分組、連接和執行任意數據轉換。如果你熟練的使用SQL,那麼這篇文章將介紹一種更直接、簡單的使用Pandas處理大多數數據操作案例。假設你對SQL非常的熟悉,或者你想有更可讀的代碼。或者您只是想在dataframe上運行一個特殊的SQL查詢。或者,也許你來自R,想要一個sqldf的替代品。
  • 一張圖看遍數據分析神器Pandas所有語法
    在Python的庫中,Pandas是目前的最愛,將它的能力進行梳理:1、直接按格式讀取超多數據源的數據,比如text、json、html、mysql等;2、對數據清洗過濾、篩選、格式轉換;3、方便的數據關聯、合併、分組統計;4、強大的時間日期處理功能;5、無縫對接matplot畫圖、也能很快的轉換到我喜歡的pyecharts
  • PANDAS: 新手教程 一 - 人工智慧遇見磐創
    # 如果你使用的是Anacondaconda install -c conda-forge pandas# 使用pip安裝Pandaspip install pandas# 導入pandasimport pandas as pd在這個練習中,我將使用著名的鐵達尼號數據集。
  • 圖解四個實用的pandas函數!
    作者:Baijayanta Roy來源:towardsdatascience編譯&內容補充:早起Python在用python進行機器學習或者日常的數據處理中,pandas是最常用的Python庫之一,熟練掌握pandas是每一個數據科學家的必備技能,本文將用代碼+圖片詳解Pandas中的四個實用函數!