中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用Pandas實現MySQL窗口函數

發布時間:2023-02-22 10:52:05 來源:億速云 閱讀:111 作者:iii 欄目:開發技術

今天小編給大家分享一下如何使用Pandas實現MySQL窗口函數的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

    一、前言

    環境:
    windows11 64位
    Python3.9
    MySQL8
    pandas1.4.2

    二、語法對比

    數據表

    本次使用的數據如下。
    使用 Python 構建該數據集的語法如下:

    import pandas as pd
    import numpy as np
    
    df1 = pd.DataFrame({ 'col1' : list(range(1,7))
                        ,'col2' : ['AA','AA','AA','BB','BB','BB']#list('AABCA')
                        ,'col3' : ['X',np.nan,'Da','Xi','Xa','xa']
                        ,'col4' : [10,5,3,5,2,None]
                        ,'col5' : [90,60,60,80,50,50]
                        ,'col6' : ['Abc','Abc','bbb','Cac','Abc','bbb']
                       })
    df2 = pd.DataFrame({'col2':['AA','BB','CC'],'col7':[1,2,3],'col4':[5,6,7]})
    df3 = pd.DataFrame({'col2':['AA','DD','CC'],'col8':[5,7,9],'col9':['abc,bcd,fgh','rst,xyy,ijk','nml,opq,wer']})

    注:直接將代碼放 jupyter 的 cell 跑即可。后文都直接使用df1df2df3調用對應的數據。

    使用 MySQL 構建該數據集的語法如下:

    with t1 as(
      select  1 as col1, 'AA' as col2, 'X' as col3, 10.0 as col4, 90 as col5, 'Abc' as col6 union all
      select  2 as col1, 'AA' as col2, null as col3, 5.0 as col4, 60 as col5, 'Abc' as col6 union all
      select  3 as col1, 'AA' as col2, 'Da' as col3, 3.0 as col4, 60 as col5, 'bbb' as col6 union all
      select  4 as col1, 'BB' as col2, 'Xi' as col3, 5.0 as col4, 80 as col5, 'Cac' as col6 union all
      select  5 as col1, 'BB' as col2, 'Xa' as col3, 2.0 as col4, 50 as col5, 'Abc' as col6 union all
      select  6 as col1, 'BB' as col2, 'xa' as col3, null as col4, 50 as col5, 'bbb' as col6 
    )
    ,t2 as(
      select  'AA' as col2, 1 as col7, 5 as col4 union all
      select  'BB' as col2, 2 as col7, 6 as col4 union all
      select  'CC' as col2, 3 as col7, 7 as col4 
    )
    ,t3 as(
      select  'AA' as col2, 5 as col8, 'abc,bcd,fgh' as col9 union all
      select  'DD' as col2, 7 as col8, 'rst,xyy,ijk' as col9 union all
      select  'CC' as col2, 9 as col8, 'nml,opq,wer' as col9 
    )
    select * from t1;

    注:直接將代碼放 MySQL 代碼運行框跑即可。后文跑 SQL 代碼時,默認帶上數據集(代碼的1~18行),僅展示查詢語句,如第19行。

    對應關系如下:

    Python 數據集MySQL 數據集
    df1t1
    df2t2
    df3t3

    row_number()

    row_number()是對檢索的數據計算行號,從1開始遞增。一般涉及分組字段和排序字段,每一個分組里的行號都唯一。
    MySQL 的row_number()函數在 Python 中可以使用groupby()+rank()實現類似的效果。

    • groupby()單列聚合時,直接將列名傳遞進去即可,如groupby('col2');如果是多列,則傳一個列表,如groupby(['col2','col6'])

    • rank()只能對一列進行排序,如df.col2.rank();當有多列排序的時候,可以使用sort_values(['col6','col5']先排好序,再聚合,然后使用累加函數cumcount()或排序函數rank()

    另外,需要注意一點,排序字段如果有重復值,在 MySQL 中會隨機返回,而 Python 中會默認使用index列進一步排序。
    具體例子如下:

    1、單列分組,單列排序
    當分組和排序都只有一列的時候,在 Python 中使用groupby()單列聚合加上rank()對單列進行排序即可。

    語言PythonMySQL
    代碼df1_1 = df1.copy()
    df1_1[‘label’] = df1_1.groupby(‘col2’)[‘col5’].rank(ascending=False,method=‘first’)
    df1_1[[‘col2’,‘col5’,‘label’]]
    select col2,col5,row_number()over(partition by col2 order by col5 desc) label from t1;
    結果如何使用Pandas實現MySQL窗口函數如何使用Pandas實現MySQL窗口函數

    2、多列分組,單列排序
    當有多列分組,則傳一個列表給groupby()函數。

    語言PythonMySQL
    代碼df1_1 = df1.copy()
    df1_1[‘label’] = df1_1.groupby([‘col2’,‘col6’])[‘col5’].rank(ascending=True,method=‘first’)
    df1_1[[‘col2’,‘col6’,‘col5’,‘label’]]
    select col2,col6,col5,row_number()over(partition by col2,col5 order by col5) label from t1;
    結果如何使用Pandas實現MySQL窗口函數如何使用Pandas實現MySQL窗口函數

    3、單列分組,多列排序
    如果是多列排序,相對復雜一些,如下【Python1】先用sort_values()排好序,然后再用groupby()聚合,然后使用rank()將排序序號加上;而【Python2】和【Python1】前2步相同,在最后一步使用了cumcount()實現編號。

    語言PythonMySQL
    代碼【Python1】
    df1_1 = df1.copy()
    df1_1[‘label’] = df1_1.sort_values([‘col6’,‘col5’],ascending=[False,True]).groupby([‘col2’])[‘col2’].rank(ascending=False,method=‘first’)
    df1_1[[‘col2’,‘col6’,‘col5’,‘label’]]
    【Python2】
    df1_1 = df1.copy()
    df1_1[‘label’] = df1_1.sort_values([‘col6’,‘col5’],ascending=[False,True]).groupby([‘col2’]).cumcount()+1
    df1_1[[‘col2’,‘col6’,‘col5’,‘label’]]
    select col2,col6,col5,row_number()over(partition by col2 order by col6 desc,col5) label from t1;
    結果如何使用Pandas實現MySQL窗口函數如何使用Pandas實現MySQL窗口函數

    3、多列分組,多列排序
    多列分組和多列排序,直接在【3、單列分組,多列排序】的基礎上,將多個分組字段添加到groupby([])中的列表即可。不再贅述。

    lead()/lag()

    lead()是從當前行向后取列值,也可以理解為將指定的列向上移動;而lag()則相反,是從當前行向前取列值,也可以理解為將指定的列向下移動。
    配合排序,二者可以進行互換,即:

    • 正序的lead()==倒序的lag()

    • 倒序的lead()==正序的lag()

    在 Python 中,可以通過shift()函數實現列值的上下移動,當傳入一個正數時,列值向下移動,當傳入一個負數時,列值向上移動
    注:關于單列/多列分組和單列/多列排序的情況,參考row_number(),不再贅述。

    1、移動1行
    移動1行時,MySQL 中直接使用lead(col1)/lag(col1)即可,使用lead(col1,1)/lag(col1,1)也沒問題,再結合升降序實現列值的上下移動。
    在 Python 中,則使用shift(-1)shift(1)實現相同的效果。以下例子是將col1下移,所以使用shift(-1)

    語言PythonMySQL
    代碼df1_1 = df1.copy()
    df1_1[‘col1_2’] = df1_1.groupby([‘col2’]).col1.shift(-1)
    df1_1[[‘col2’,‘col1’,‘col1_2’]].sort_values([‘col2’,‘col1’],ascending=[True,True])
    【MySQL1】
    select col2,col1,lead(col1)over(partition by col2 order by col1) col1_2 from t1;
    【MySQL2】
    select col2,col1,lag(col1)over(partition by col2 order by col1 desc) col1_2 from t1;
    結果如何使用Pandas實現MySQL窗口函數如何使用Pandas實現MySQL窗口函數

    2、移動多行
    移動多行的時候,MySQL 中需要指定移動行數,如下例子,移動2行,使用lead(col1,2)lag(col1,2),再結合升降序實現列值的上下移動。
    在 Python 中,則修改傳遞給shift()函數的參數值即可,如下例子,使用shift(2)向上移動2行。

    語言PythonMySQL
    代碼df1_1 = df1.copy()
    df1_1[‘col1_2’] = df1_1.groupby([‘col2’]).col1.shift(2) # 通過shift控制
    df1_1[[‘col2’,‘col1’,‘col1_2’]].sort_values([‘col2’,‘col1’],ascending=[True,True])
    【MySQL1】
    select col2,col1,lead(col1,2)over(partition by col2 order by col1 desc) col1_2 from t1;
    【MySQL2】
    select col2,col1,lag(col1,2)over(partition by col2 order by col1) col1_2 from t1;
    結果如何使用Pandas實現MySQL窗口函數如何使用Pandas實現MySQL窗口函數

    rank()/dense_rank()

    rank()dense_rank()用于計算排名。rank()排名可能不連續,就是當有重復值的時候,會并列使用小的排名,而重復值之后的排名則按照重復個數疊加往后排,如一組數(10,20,20,30),按升序排列是(1,2,2,4);而dense_rank()的排名是連續的,還是上面的例子,按升序排列是(1,2,2,3)。
    而在 Python 中,排序同樣是通過rank()函數實現,只是methodrow_number()使用的不一樣。實現rank()的效果,使method='min',而實現dense_rank()的效果,使用method='dense'。除了這兩種和在row_number()中使用的method='first',還有averagemaxaverage的邏輯是所有值進行不重復連續排序之后,將分組內的重復值的排名進行平均,還是上面的例子,按升序排列是(1,2.5,2.5,4),maxmin相反,使用的是分組內重復值取大的排名進行排序,還是上面的例子,按升序排列是(1,3,3,4)。
    同樣地,排序字段如果有重復值,在 MySQL 中會隨機返回,而 Python 中會默認使用index列進一步排序。

    注:關于單列/多列分組和單列/多列排序的情況,參考row_number(),不再贅述。
    1、rank()
    Python 中使用rank(method='min')實現 MySQL 中的rank()窗口函數。

    語言PythonMySQL
    代碼df1_1 = df1.copy()
    df1_1[‘label’] = df1_1.groupby([‘col2’])[‘col5’].rank(ascending=True,method=‘min’)
    df1_1[[‘col2’,‘col5’,‘label’]]
    select col2,col5,rank()over(partition by col2 order by col5) col1_2 from t1;
    結果如何使用Pandas實現MySQL窗口函數如何使用Pandas實現MySQL窗口函數

    2、dense_rank()
    Python 中使用rank(method='dense')實現 MySQL 中的rank()窗口函數。

    語言PythonMySQL
    代碼df1_1 = df1.copy()
    df1_1[‘label’] = df1_1.groupby([‘col2’])[‘col5’].rank(ascending=True,method=‘dense’)
    df1_1[[‘col2’,‘col5’,‘label’]]
    select col2,col5,dense_rank()over(partition by col2 order by col5) col1_2 from t1;
    結果如何使用Pandas實現MySQL窗口函數如何使用Pandas實現MySQL窗口函數

    first_value()

    MySQL 中的窗口函數first_value()是取第一個值,可用于取數據默認順序的第一個值,也可以通過排序,取某一列的最大值或最小值。
    在 Pandas 中,也有相同功能的函數first()
    不過,first_value()是窗口函數,不會影響表單內的其他字段,但first()時一個普通函數,只返回表單中的第一個值對應的行,所以在 Python 中要實現first_value()窗口函數相同的結果,需要將first()函數返回的結果,再通過表聯結關聯回原表(具體例子如下)。在 Python 中,還有一個last()函數,和first()相反,結合排序,也可以實現相同效果,和first()可互換,讀者可自行測試,不再贅述。

    注:關于單列/多列分組和單列/多列排序的情況,參考row_number(),不再贅述。
    1、取最大值
    MySQL 中,對col5降序,便可通過first_value()取得最大值。同樣,在 Python 中,使用sort_values()col5進行降序,便可通過first()取得最大值,然后再merge()回原表。

    語言PythonMySQL
    代碼df1_1 = df1.copy()
    df1_2 = df1_1.sort_values([‘col5’],ascending=[False]).groupby([‘col2’]).first().reset_index()[[‘col2’,‘col5’]] # 最好加個排序
    df1[[‘col2’,‘col5’]].merge(df1_2,on = ‘col2’,how = ‘left’,suffixes=(‘’,‘_2’))
    select col2,col5,first_value(col5)over(partition by col2 order by col5 desc) col5_2 from t1;
    結果如何使用Pandas實現MySQL窗口函數如何使用Pandas實現MySQL窗口函數

    2、取最小值
    取最小值,則是在取最大值的基礎上,改變col5的排序即可,由降序改為升序。

    語言PythonMySQL
    代碼df1_1 = df1.copy()
    df1_2 = df1_1.sort_values([‘col5’],ascending=[True]).groupby([‘col2’]).first().reset_index()[[‘col2’,‘col5’]]
    df1[[‘col2’,‘col5’]].merge(df1_2,on = ‘col2’,how = ‘left’,suffixes=(‘’,‘_2’))
    select col2,col5,first_value(col5)over(partition by col2 order by col5) col5_2 from t1;
    結果如何使用Pandas實現MySQL窗口函數如何使用Pandas實現MySQL窗口函數

    count()/sum()

    MySQL 的聚合函數count()sum()等,也可以加上over()實現窗口函數的效果。

    • count()可以用于求各個分組內的個數,也可以對分組內某個列的值進行累計。

    • sum()可以用于對各個分組內某個列的值求和,也可以對分組某個列的值進行累加。

    在 Python 中,針對累計和累加的功能,可以使用groupby()+cumcount()groupby()+cumsum()實現(如下例子1和2),而針對分組內的計數和求和,可以通過groupby()+count()groupby()+sum()實現(如下例子3和4)。

    注:關于單列/多列分組和單列/多列排序的情況,參考row_number(),不再贅述。
    1、升序累計
    Python 中使用sort_values()+groupby()+cumcount()實現 MySQL count(<col_name>)over(partition by <col_name> order by <col_name>)效果。

    語言PythonMySQL
    代碼df1_1 = df1.copy()
    df1_1[&lsquo;col5_2&rsquo;] = df1_1.sort_values([&lsquo;col5&rsquo;,&lsquo;col1&rsquo;],ascending=[True,False]).groupby(&lsquo;col2&rsquo;).col5.cumcount()+1
    df1_1[[&lsquo;col2&rsquo;,&lsquo;col5&rsquo;,&lsquo;col5_2&rsquo;]]
    select col2,col5,count(col5)over(partition by col2 order by col5,col1) col5_2 from t1;
    結果如何使用Pandas實現MySQL窗口函數如何使用Pandas實現MySQL窗口函數

    2、升序累加
    Python 中使用sort_values()+groupby()+cumsum()實現 MySQL sum(<col_name>)over(partition by <col_name> order by <col_name>)效果。

    語言PythonMySQL
    代碼df1_1 = df1.copy()
    df1_1[&lsquo;col5_2&rsquo;] = df1_1.sort_values([&lsquo;col5&rsquo;,&lsquo;col1&rsquo;],ascending=[True,False]).groupby(&lsquo;col2&rsquo;).col5.cumsum()
    df1_1[[&lsquo;col2&rsquo;,&lsquo;col5&rsquo;,&lsquo;col5_2&rsquo;]]
    select col2,col5,sum(col5)over(partition by col2 order by col5,col1) col5_2 from t1;
    結果如何使用Pandas實現MySQL窗口函數如何使用Pandas實現MySQL窗口函數

    3、分組計數
    Python 中使用sort_values()+groupby()+count()實現 MySQL count(<col_name>)over(partition by <col_name>)效果。

    語言PythonMySQL
    代碼df1_1 = df1.copy()
    df1_2 = df1_1.sort_values([&lsquo;col5&rsquo;,&lsquo;col1&rsquo;],ascending=[True,False]).groupby(&lsquo;col2&rsquo;).col5.count().reset_index()
    df1_1[[&lsquo;col2&rsquo;,&lsquo;col5&rsquo;]].merge(df1_2,how=&lsquo;left&rsquo;,on=&lsquo;col2&rsquo;,suffixes=(&lsquo;&rsquo;,&lsquo;_2&rsquo;))
    select col2,col5,count(col5)over(partition by col2) col5_2 from t1;
    結果如何使用Pandas實現MySQL窗口函數如何使用Pandas實現MySQL窗口函數

    4、分組求和
    Python 中使用sort_values()+groupby()+sum()實現 MySQL sum(<col_name>)over(partition by <col_name>)效果。

    語言PythonMySQL
    代碼df1_1 = df1.copy()
    df1_2 = df1_1.sort_values([&lsquo;col5&rsquo;,&lsquo;col1&rsquo;],ascending=[True,False]).groupby(&lsquo;col2&rsquo;).col5.sum().reset_index()
    df1_1[[&lsquo;col2&rsquo;,&lsquo;col5&rsquo;]].merge(df1_2,how=&lsquo;left&rsquo;,on=&lsquo;col2&rsquo;,suffixes=(&lsquo;&rsquo;,&lsquo;_2&rsquo;))
    select col2,col5,sum(col5)over(partition by col2) col5_2 from t1;
    結果如何使用Pandas實現MySQL窗口函數如何使用Pandas實現MySQL窗口函數

    三、小結

    MySQL 的窗口函數效果,在 Python 中,基本都需要經過多個步驟,使用多個函數進行組合處理。窗口函數涉及到分組字段和排序字段,在 Python 中對應使用groupby()sort_values(),所以基本上在 Python 中實現窗口函數的效果都需要使用到這兩個函數輔助處理數據。剩下的聚合形式就根據聚合窗口函數的特性做修改,對應關系如下:

    MySQL 窗口函數Python 對應函數
    row_number()rank()
    lead()/lag()shift()
    rank()/dense_rank()rank()
    first_value()first()
    count()count()、cumcount()
    sum()sum()、cumsum()

    以上就是“如何使用Pandas實現MySQL窗口函數”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    广元市| 昌图县| 阜阳市| 当涂县| 伊金霍洛旗| 汤原县| 河曲县| 门头沟区| 尖扎县| 政和县| 大关县| 上饶县| 安康市| 中阳县| 济南市| 长寿区| 通州区| 讷河市| 盐城市| 湘潭市| 阳东县| 榆树市| 长海县| 响水县| 虎林市| 永昌县| 吉木萨尔县| 呼和浩特市| 庆元县| 油尖旺区| 峨眉山市| 萨迦县| 西华县| 庆安县| 灵武市| 余江县| 施秉县| 东丽区| 天等县| 额敏县| 连城县|