對比MySQL學習Pandas的groupby分組聚合

2021-03-02 腳本之家

本文經授權轉自公眾號 凹凸數據(ID:alltodata)

如若轉載請聯繫原公眾號


1)都是用來處理表格數據


不管是mysql,還是pandas,都是處理像excel那樣的二維表格數據的。對於一個二維表,每一行都可以看作是一條記錄,每一列都可以看作是欄位。


2)分組聚合的風格不同


學過mysql的人都知道,mysql在做數據處理和統計分析的時候,有一個很大的痛點:語法順序和執行順序不一致,這就導致很多初學者很容易寫錯sql語句。


業界處理像excel那樣的二維表格數據,通常有如下兩種風格:

* DSL風格:使用面向對象的方式來操作,pandas就是採用這種方式,通俗說就是「語法順序和執行順序一致」。
* SQL風格:寫sql語句來處理。


3)從代碼角度,說明兩者的不同


① mysql

語法順序:

SELECT Column1, Column2, mean(Column3), sum(Column4)
FROM SomeTable
WHERE Condition 1
GROUP BY Column1, Column2
HAVING Condition2

邏輯執行順序:

from...where...group...select...having...limit

② pandas

語法順序和邏輯執行順序:

df[Condition1].groupby([Column1,Column2],as_index=False).agg({Column3: "mean",Column4:"sum"})

③ 圖示說明


首先from相當於取出MySQL中的一張表,對比pandas就是得到了一個df表對象。


然後就是執行where篩選,對比pandas就相當於寫一個condition1過濾條件,做一個分組前的篩選篩選。


接著就是執行group分組條件,對比pandas就是寫一個groupby條件進行分組。


再接著就是執行select條件,聚合函數就是寫在select後面的,對比pandas就是執行agg()函數,在其中針對不同的列執行count、max、min、sum、mean聚合函數。


最後執行的是having表示分組後的篩選,在pandas中,通過上圖可以發現我們得到了一個df1對象,針對這個df1對象,我們再做一次篩選,也表示分組後的篩選。


綜上所述:只要你的邏輯想好了,在pandas中,由於語法順序和邏輯執行順序是一致的,你就按照邏輯順序寫下去,就很容易了。


4)用一個例子講述MySQL和Pandas分組聚合


① 求不同deptno(部門)下,sal(工資)大於8000的部門、工資;



② mysql中代碼執行如下

select deptno,sum(sal) sums
from emp
group by deptno
having sums > 9000;

結果如下:


③ pandas中代碼執行如下

df = pd.read_excel(r"C:\Users\黃偉\Desktop\emp.xlsx")
display(df)

df = df.groupby("deptno",as_index=False).agg({"sal":"sum"})
display(df)

df1 = df[df["sal"]>9000]
display(df1)

結果如下:



1)原理圖


2)原理說明

split:按照指定規則分組,由groupby實現;

apply:針對每個小組,使用函數進行操作,得到結果,由agg()函數實現;

combine:將每一組得到的結果,匯總起來,得到最終結果;

注意:combine這一步是自動完成的,因此針對pandas中的分組聚合,我們只需要學習兩個內容,① 學習怎麼分組;② 學習如何針對每個分組中的數據,進行對應的邏輯操作;



我們可以通過groupby方法來對Series或DataFrame對象實現分組操作,該方法會返回一個分組對象。但是,如果直接查看(輸出)該對象,並不能看到任何的分組信息。


1)groupby()函數語法

① 語法如下

* groupby(by=["欄位1","欄位2",...],as_index=True)

② 參數說明

* by參數傳入的分組欄位,當只有一個欄位的時候,可以直接寫by="欄位1"。當多欄位聯合分組的時候,就寫成列表形式by=["欄位1","欄位2"]。
* as_index參數的使用如圖所示



③ 參數as_index的使用說明

x = {"name":["a","a","b","b","c","c","c"],"num":[2,4,0,5,5,10,15]}
df = pd.DataFrame(x)
display(df)

df.groupby("name",as_index=True).agg({"num":"sum"})
df.groupby("name",as_index=False).agg({"num":"sum"})

結果如下:


2)groupby分組對象的常用方法或屬性。


① groups屬性:返回一個字典,key表示組名,value表示這一組中的所有記錄;


② size()方法:返回每個分組的記錄數;

x = {"name":["a","a","b","b","c","c","c"],"num":[2,4,0,5,5,10,15]}
df = pd.DataFrame(x)
display(df)

df.groupby("deptno").groups
df.groupby("deptno").size()

結果如下:


3)使用for循環列印groupby()分組對象中每一組的具體數據

x = {"name":["a","a","b","b","c","c","c"],"num":[2,4,0,5,5,10,15]}
df = pd.DataFrame(x)
display(df)

groupdf = df.groupby("name")
for (x,y) in groupdf:
display(x, y)

結果如下:


4)groupby()分組參數的4種形式

使用groupby進行分組時,分組的參數可以是如下的形式:
* 單欄位分組:根據df中的某個欄位進行分組。
* 多欄位分組:根據df中的多個欄位進行聯合分組。
* 字典或Series:key指定索引,value指定分組依據,即value值相等的記錄,會分為一組。
* 自定義函數:接受索引,索引相同的記錄,會分為一組。

使用如下數據演示這4種分組參數:

df = pd.DataFrame({"部門":["A", "A", "B", "B"],
"小組":["g1", "g2", "g1", "g2"],
"利潤":[10, 20, 15, 28],
"人員":["a", "b", "c", "d"],
"年齡":[20, 15, 18, 30]})
display(df)

結果如下:

① 單欄位分組:根據df中的某個欄位進行分組。

g = df.groupby("部門")
display(g)

for (x,y) in g:
display(x, y)

結果如下:

② 多欄位分組:根據df中的多個欄位進行聯合分組。

g = df.groupby("部門")
display(g)

for (x,y) in g:
display(x, y)

結果如下:


③ 字典:key指定索引,value指定分組依據,即value值相等的記錄,會分為一組。

g = df.groupby({0:1, 1:1, 2:1, 3:2})
display(g)

for (x,y) in g:
display(x, y)

結果如下:



④ Series:分組排序(很重要)

df = pd.DataFrame({"部門":["A", "A", "A", "B", "B", "B"],
"利潤":[10, 32, 20, 15, 28, 10],
"銷售量":[20, 15, 33, 18, 30, 22]})
display(df)

df["排名"] = df["銷售量"].groupby(df["部門"]).rank()
df

結果如下:


⑤ 自定義函數:將部門A、B分為一組,C單獨成為一組(很特別的需求)

df = pd.DataFrame({"部門":["A", "A", "B", "B", "C", "C"],
"小組":["g1", "g2", "g1", "g2", "g1", "g2"],
"利潤":[10, 20, 15, 28, 12, 14],
"人員":["a", "b", "c", "d", "e", "f"],
"年齡":[20, 15, 18, 30, 23, 34]})
df = df.set_index("部門")
display(df)

def func(x):
if x=="A" or x=="B":
return 0
else:
return 1

g = df.groupby(func)
display(g)

for (x,y) in g:
display(x, y)

結果如下:



當使用了groupby()分組的時候,得到的就是一個分組對象。當沒有使用groupby()分組的時候,整張表可以看成是一個組,也相當於是一個分組對象。


針對分組對象,我們既可以直接調用聚合函數sum()、mean()、count()、max()、min(),還可以調用分組對象的agg()方法,然後像agg()中傳入指定的參數。


1)直接針對分組對象,調用聚合函數


① 針對df整張表,直接調用聚合函數

df = pd.DataFrame({"部門":["A", "A", "B", "B", "C", "C"],
"小組":["g1", "g2", "g1", "g2", "g1", "g2"],
"利潤":[10, 20, 15, 28, 12, 14],
"人員":["a", "b", "c", "d", "e", "f"],
"年齡":[20, 15, 18, 30, 23, 34]})
display(df)

df["利潤"].mean()
df[["年齡","利潤"]].mean()

結果如下:

② 針對df分組後的對象,直接調用聚合函數

df = pd.DataFrame({"部門":["A", "A", "B", "B", "C", "C"],
"小組":["g1", "g2", "g1", "g2", "g1", "g2"],
"利潤":[10, 20, 15, 28, 12, 14],
"人員":["a", "b", "c", "d", "e", "f"],
"年齡":[20, 15, 18, 30, 23, 34]})
display(df)

df.groupby("部門")["利潤"].mean()
df.groupby("部門").mean()

結果如下:

2)直接針對分組對象,調用agg()函數(很重要)


下面知識的講解,涉及到「聚合函數字符串」,這是我自己起的名字,類似於"sum"、"mean"、"count"、"max"、"min",都叫做「聚合函數字符串」。同時還需要注意一點,agg()函數中還有一個axis參數,用於指定行、列。

* df.agg("mean")
* df.agg(["mean", "sum", "max"])
* df.agg({"利潤":["mean", "sum"] , "年齡":["max", "min"]})
* df.agg(lambda x: x.mean())

① 傳入單個聚合函數字符串

df = pd.DataFrame({"部門":["A", "A", "B", "B"],
"利潤":[10, 20, 15, 28],
"年齡":[20, 15, 18, 30]})
display(df)

df1 = df.groupby("部門").agg("mean")
display(df1)

結果如下:


② 傳入多個聚合函數字符串

df = pd.DataFrame({"部門":["A", "A", "B", "B"],
"利潤":[10, 20, 15, 28],
"年齡":[20, 15, 18, 30]})
display(df)

df1 = df.groupby("部門").agg(["sum","mean"])
display(df1)

結果如下:

③ 傳入一個字典:可以針對不同的列,提供不同的聚合信息。

df = pd.DataFrame({"部門":["A", "A", "B", "B"],
"利潤":[10, 20, 15, 28],
"年齡":[20, 15, 18, 30]})
display(df)

df1 = df.groupby("部門").agg({"利潤":["sum","mean"],"年齡":["max","min"]})
display(df1)

結果如下:

④ 傳入自定義函數

df = pd.DataFrame({"部門":["A", "A", "A", "B", "B", "B"],
"利潤":[10, 32, 20, 15, 28, 10],
"銷售量":[20, 15, 33, 18, 30, 22]})
display(df)

df.groupby("部門").agg(lambda x:x.max()-x.min())

結果如下:


更多精彩

在公眾號後臺對話框輸入以下關鍵詞

查看更多優質內容!

女朋友 | 大數據 | 運維 | 書單 | 算法

大數據 | JavaScript | Python | 黑客

AI | 人工智慧 | 5G | 區塊鏈

機器學習 | 數學 | 送書

相關焦點

  • Pandas中groupby的這些用法你都知道嗎?
    groupby是pandas中用於數據分析的一個重要功能,其功能與SQL中的分組操作類似,但功能卻更為強大。理解gro理解groupby的原理可參考官網給出的解釋:其中:groupby首先要指定分組原則,這也是groupby函數的第一步,其常用參數包括:by,分組欄位,可以是列名/series/字典/函數,常用為列名axis,指定切分方向,默認為0,表示沿著行切分as_index,是否將分組列名作為輸出的索引,默認為True;當設置為
  • 數據處理技巧 | 帶你了解Pandas.groupby() 常用數據處理方法
    今天我們繼續推出一篇數據處理常用的操作技能匯總:靈活使用pandas.groupby()函數,實現數據的高效率處理,主要內容如下:pandas.groupby()三大主要操作介紹說到使用Python進行數據處理分析,那就不得不提其優秀的數據分析庫-Pandas,
  • Pandas入門(分組聚合)
    一.數據分組import
  • MySQL最常用分組聚合函數
    [LIMIT {[offset,] row_count | row_count OFFSET offset}]分組SELECT的基本格式:  select [聚合函數] 欄位名 from 表名    [where 查詢條件]    [group by 欄位名]    [having 過濾條件]1、
  • pandas系列(三)Pandas分組
    分組函數的基本內容:2. groupby對象的特點三、聚合、過濾和變換1. 聚合(Aggregation)2.分組函數的基本內容:(a)根據某一列分組grouped_single = df.groupby('School')經過groupby後會生成一個groupby對象,該對象本身不會返回任何東西,只有當相應的方法被調用才會起作用
  • pandas中的groupby方法應用
    ★本次主要學習如何使用pandas對數據進行分析統計,特別是groupby函數的使用,進行分組統計。
  • Pandas的GroupBy機制
    在數據分析過程中,描述數據是對具有某些特徵的列進行的,分析結果也需要對具體的組進行對比分析,GroupBy就是能滿足這種需求的一種分組機制。GroupBy的應用包括三個流程:(split - apply - combine)Splitting: 將數據按需求分組;Applying: 對每個小組進行函數操作;Combining: 合併結果。
  • 【Python基礎】Pandas筆記---深入Groupby,它的功能沒有你想的這麼簡單
    在Applying中,可能希望做以下其中一項:聚集(Aggregation):計算每個組的匯總統計信息(或統計信息),例如計算分組的和、均值、個數等。轉換(Transformation):執行一些特定組的計算並返回一個like-indexed對象。過濾(Filteration):根據判斷為真或假的組計算,丟棄一些組。
  • 從pandas中的這幾個函數,我看懂了道家「一生二、二生三、三生萬物」
    從數據讀寫到預處理、從數據分析到可視化,pandas提供了一站式服務。而其中的幾個聚合統計函數,不僅常用更富有辯證思想,細品之下不禁讓人拍手稱快、直呼叫好!當然,groupby的強大之處在於,分組依據的欄位可以不只一列。
  • pandas使用的100個trick
    pandas是處理數據的必備工具,可以方便地篩選,統計,分組集計,轉換等操作,而且pandas(熊貓)這麼可愛,誰能不愛呢()中有用的參數•Trick 3: datetime對象可用接口•Trick 4: 將小類別統一划分為一類•Trick 5: 用多個篩選條件篩選數據的清爽寫法•Trick 6: 把連續變量分組(cut )•Trick 7: 將集計過的結果與原數據合併•Trick 8: groupby後獲得某分組Trick 1: 一行查看數據總體情況import pandas_profilingpandas_profiling.ProfileReport
  • 一場pandas與SQL的巔峰大戰(二)
    上一篇文章一場pandas與SQL的巔峰大戰中,我們對比了pandas與SQL常見的一些操作,我們的例子雖然是以MySQL為基礎的,但換作其他的資料庫軟體,也一樣適用。工作中除了MySQL,也經常會使用Hive SQL,相比之下,後者有更為強大和豐富的函數。本文將延續上一篇文章的風格和思路,繼續對比Pandas與SQL,一方面是對上文的補充,另一方面也繼續深入學習一下兩種工具。
  • 不再糾結,一文詳解pandas中的map、apply、applymap、groupby、agg...
    二、非聚合類方法這裡的非聚合指的是數據處理前後沒有進行分組操作,數據列的長度沒有發生改變,因此本章節中不涉及groupby()。三、聚合類方法有些時候我們需要像SQL裡的聚合操作那樣將原始數據按照某個或某些離散型的列進行分組再求和、平均數等聚合之後的值,在pandas中分組運算是一件非常優雅的事。
  • 十分鐘學習pandas!pandas常用操作總結!
    學習Python, 當然少不了pandas,pandas是python數據科學中的必備工具,熟練使用pandas是從sql boy/girl 跨越到一名優秀的數據分析師傅的必備技能。這篇pandas常用操作總結幫大家回顧下pandas的常用語法,尤其是我們分析數據時常用的方法。
  • 十分鐘學習pandas! pandas常用操作總結!
    學習Python, 當然少不了pandas,pandas是python數據科學中的必備工具
  • Pandas常用的數據處理方法
    4、數據聚合4.1 數據分組pandas中的數據分組使用groupby方法,返回的是一個GroupBy對象,對分組之後的數據,我們可以使用一些聚合函數進行聚合,比如求平均值mean:df = pd.DataFrame
  • 【數據分析】Pandas
    5、數據分組和聚合在數據分析當中,我們有時需要將數據拆分,然後在每一個特定的組裡進行運算,這些操作通常也是數據分析工作中的重要環節。本章學習內容:分組(GroupBY機制)聚合(組內應用某個函數)apply
  • Pandas的crosstab函數
    目錄Pandas crosstab()與pivot_table()和groupby()的比較你可以在這個GitHub repo上下載本文的notebook:https://github.com/BexTuychiev/medium_stories/tree/master/hardest_of_pandas2設置
  • Pandas的介紹與基本使用
    3.4、數據分組和聚合在數據分析當中,我們有時需要將數據拆分,然後在每一個特定的組裡進行運算,這些操作通常也是數據分析工作中的重要環節。分組聚合相對來說也是一個稍微難理解的點,需要各位有一定的功力來學習.
  • Pandas筆記---深入Groupby詳解
    最簡單的是我們通過agg()方法來調用一些Python內置函數進行聚合計算,常用的內置函數為:mean、median、sum、size、count、std、describe、min、max等。363311 3964173 524387.842105363317 4244734 787231.666667363318 4072414 -110147.829268363319 4378860 250463.10778430025 rows × 2 columns對不同的列使用不同的聚合可以通過字典的方式實現
  • 掌握pandas中的transform
    ❝本文示例代碼及文件已上傳至我的Github倉庫https://github.com/CNFeffery/DataScienceStudyNotes❞1 簡介開門見山,在pandas中,transform是一類非常實用的方法,通過它我們可以很方便地將某個或某些函數處理過程(非聚合)作用在傳入數據的每一列上,從而返回與輸入數據形狀一致的運算結果