作為一名數(shù)據(jù)分析師躁绸,平常用的最多的工具是SQL(包括MySQL和Hive SQL等)虱歪。對于存儲在數(shù)據(jù)庫中的數(shù)據(jù)霹抛,自然用SQL提取會比較方便,但有時我們會處理一些文本數(shù)據(jù)(txt,csv)轮听,這個時候就不太好用SQL了骗露。Python也是分析師常用的工具之一,尤其pandas更是一個數(shù)據(jù)分析的利器血巍。雖然二者的語法萧锉,原理可能有很大差別,但在實現(xiàn)的功能上述寡,他們有很多相通的地方柿隙,這里特進行一個總結(jié)叶洞,方便大家對比學(xué)習(xí)~
本次學(xué)習(xí)的數(shù)據(jù)是虛構(gòu)的訂單數(shù)據(jù),和實際業(yè)務(wù)無關(guān)禀崖,目的只是為了學(xué)習(xí)衩辟。大概長下面這樣子,分別表示波附,自增id艺晴,訂單時間,用戶id掸屡,訂單id封寞,訂單金額。
我們將用pandas和SQL來實現(xiàn)同樣的目標(biāo)仅财,以此來聯(lián)系二者狈究,達到共同學(xué)習(xí)的目的。數(shù)據(jù)可以在公眾號后臺回復(fù)“對比”獲取满着,你將得到本文所有的excel數(shù)據(jù)和SQL腳本數(shù)據(jù)以及本文的清晰PDF版本谦炒,便于實操和查看贯莺。
準(zhǔn)備工作:
-
pandas準(zhǔn)備风喇,我們本次采用jupyter notebook進行演示。
import pandas as pdorder_data = pd.read_csv('order.csv')
-
SQL 準(zhǔn)備
只需將我提供的SQL文件運行一下即可將數(shù)據(jù)插入數(shù)據(jù)庫表中缕探。推薦使用navicate客戶端連接數(shù)據(jù)庫魂莫。
開始學(xué)習(xí)
1.查看全部數(shù)據(jù)或者前n行數(shù)據(jù)
查看全部數(shù)據(jù),pandas中直接打印dataframe對象即可爹耗,此處是order_data耙考。而在SQL中,需要執(zhí)行的語句是select * from t_order;
表示從t_order表中查詢?nèi)康臄?shù)據(jù)潭兽,*號表示查詢所有的字段倦始。結(jié)果如下:(點擊圖片可以查看大圖)
如果只想查看前10行數(shù)據(jù)呢。pandas可以調(diào)用head(n)方法山卦,n是行數(shù)鞋邑。MySQL可以使用limit n,n同樣表示行數(shù)账蓉。(點擊圖片可以查看大圖)
2.查詢特定列的數(shù)據(jù)
有的時候我們只想查看某幾列的數(shù)據(jù)枚碗。在pandas里可以使用中括號或者loc,iloc等多種方式進行列選擇铸本,可以選擇一列或多列肮雨。loc方式可以直接寫列名,iloc方式需要指定索引箱玷,即第幾列怨规。SQL里只需寫相應(yīng)的列名即可陌宿,舉例如下,實際操作一下更容易理解波丰,選擇一種自己習(xí)慣的即可限番。(點擊圖片可以查看大圖)
3.查詢特定列去重后的數(shù)據(jù)
例如我們想查看一共有多少人(去重過的)下過單。pandas里有unique方法呀舔,SQL里有distinct關(guān)鍵字弥虐。如下面圖左側(cè)代碼所示。兩種方式輸出的結(jié)果都含有9個uid媚赖,并且知道是哪9個霜瘪。如果僅僅想知道有多少個uid,不關(guān)注具體值的話惧磺,可以參考右邊的SQL颖对,pandas用nunique()方法實現(xiàn),而SQL里就需要用到一個count聚合函數(shù)與distinct組合的方式磨隘,表示去重并計數(shù)缤底。(點擊圖片可以查看大圖)
4.查詢帶有1個條件的數(shù)據(jù)
例如我們要查詢uid為10003的所有記錄。pandas需要使用布爾索引的方式番捂,而SQL中需要使用where關(guān)鍵字个唧。指定條件時,可以指定等值條件设预,也可以使用不等值條件徙歼,如大于小于等。但一定要注意數(shù)據(jù)類型鳖枕。例如如果uid是字符串類型魄梯,就需要將10003加引號,這里是整數(shù)類型所以不用加宾符。代碼如下:(點擊圖片可以查看大圖)
5.查詢帶有多個條件的數(shù)據(jù)酿秸。
-
多個條件同時滿足的情況
在前一小結(jié)基礎(chǔ)上,pandas需要使用&符號連接多個條件魏烫,每個條件需要加上小括號辣苏;SQL需要使用and關(guān)鍵字連接多個條件。例如我們查詢uid為10003并且金額大于50的記錄则奥。兩種方式的實現(xiàn)代碼如下:(點擊圖片可以查看大圖)
image -
多個條件滿足其中一個的情況
與多個條件同時滿足使用&相對應(yīng)的考润,我們使用|符號表示一個條件滿足的情況,而SQL中則用or關(guān)鍵字連接各個條件表示任意滿足一個读处。例如我們查詢uid為10003或者金額大于50的記錄糊治。(點擊圖片可以查看大圖)
image這里需要特別說明的是有一種情況是需要判斷某字段是否為空值。pandas的空值用nan表示罚舱,其判斷條件需要寫成isna()井辜,或者notna()绎谦。例如
#查找uid不為空的記錄order_data[order_data['uid'].notna()]#查找uid為空的記錄order_data[order_data['uid'].isna()]
MySQL相應(yīng)的判斷語句需要寫成 is null 或者is not null。
select * from t_order where uid is not null;select * from t_order where uid is null;
還需要注意的是粥脚,空字符串或者空格雖然是有值的窃肠,但由于“不顯示”出來,我們通常認(rèn)為是空值刷允。這種情況的判斷條件和前面一樣使用等號即可冤留。感興趣的朋友可以自己嘗試一下。
6.group by聚合操作
使用group by時树灶,通常伴隨著聚合操作纤怒,這時候需要用到聚合函數(shù)。前面提到的count是一種聚合函數(shù)天通,表示計數(shù)泊窘,除此外還有sum表示求和,max,min表示最大最小值等像寒。pandas和SQL都支持聚合操作烘豹。例如我們求每個uid有多少訂單量。兩種工具的操作如下:(點擊圖片可以查看大圖)
如果想要同時對不同的字段進行不同的聚合操作诺祸。例如目標(biāo)變成:求每個uid的訂單數(shù)量和訂單總金額携悯。寫法會稍微不同一些,如下圖所示序臂。(點擊圖片可以查看大圖)
更進一步的蚌卤,我們可以對結(jié)果的數(shù)據(jù)集進行重新命名。pandas可以使用rename方法奥秆,MySQL可以使用as 關(guān)鍵字進行結(jié)果的重命名。(點擊圖片可以查看大圖)
7.join相關(guān)操作
join相關(guān)的操作有inner join咸灿,left join构订,right join,full join避矢,等悼瘾。pandas中統(tǒng)一通過pd.merge方法,設(shè)置不同的參數(shù)即可實現(xiàn)不同的dataframe的連接审胸。而SQL里就可以直接使用相應(yīng)的關(guān)鍵字進行兩個表的連接亥宿。為了演示,我們此處引入一個新的數(shù)據(jù)集砂沛,user.csv(對應(yīng)t_user表)烫扼。包含了用戶的昵稱,年齡信息碍庵。數(shù)據(jù)樣例如下所示映企。(點擊圖片可以查看大圖)
-
left join
首先需要把數(shù)據(jù)加載進來:
user_data = pd.read_csv('user.csv')
pandas的merge函數(shù)傳入4個參數(shù)悟狱,第一個是連接的主表,第二個是連接從表堰氓,第三個連接的key值挤渐,第四個是連接的方式,how為left時表示是左連接双絮。SQL操作時基本也是同樣的邏輯浴麻,要指定主表,從表囤攀,連接方式和連接字段白胀。此處我們使用user連接order并查詢所有字段和所有記錄。具體代碼如下所示抚岗,由于我們的數(shù)據(jù)沒有空值或杠,所以體現(xiàn)不出左連接的特點,感興趣的讀者可以自己嘗試下宣蔚。(點擊圖片可以查看大圖)
-
其他連接方式
如果要實現(xiàn)inner join向抢,outer join,right join胚委,pandas中相應(yīng)的how參數(shù)為inner或者不填挟鸠,outer,right亩冬。SQL也是同樣直接使用對應(yīng)的關(guān)鍵字即可艘希。其中inner join 可以縮寫為join。本例子中inner join 和left join的結(jié)果是一樣的硅急,在這里不作結(jié)果展示覆享,pandas和SQL代碼如下。
pd.merge(user_data, order_data, on='uid', how='inner')
SELECT * FROM t_user ainner join t_order bon a.uid = b.uid;
8.union操作
union相關(guān)操作分為union和union all兩種营袜。二者通常用于將兩份含有同樣字段的數(shù)據(jù)縱向拼接起來的場景撒顿。但前者會進行去重。例如荚板,我現(xiàn)在有一份order2的訂單數(shù)據(jù)凤壁,包含的字段和order數(shù)據(jù)一致,想把兩者合并到一個dataframe中跪另。SQL場景下也是期望將order2表和order表合并輸出拧抖。執(zhí)行的代碼如下:(點擊圖片可以查看大圖)
以上是沒有去重的情況,如果想要去重免绿,SQL需要用union關(guān)鍵字唧席。而pandas則需要加上去重操作。
order_union = pd.concat([order_data, order_data2]).drop_duplicates()
select * fromt_order union select * fromt_order2
9.排序操作
我們在實際工作中經(jīng)常需要按照某一列字段進行排序。pandas中的排序使用sort_values方法袱吆,SQl中的排序可以使用order_by關(guān)鍵字厌衙。我們用一個實例說明:按照每個uid的訂單數(shù)從高到低排序。這是在前面聚合操作的基礎(chǔ)上的進行的绞绒。相應(yīng)的代碼可以參考下方:(點擊圖片可以查看大圖)
排序時婶希,asc表示升序,desc表示降序蓬衡,能看到兩種方法都指定了排序方式喻杈,原因是默認(rèn)是會按照升序排列。在此基礎(chǔ)上狰晚,可以做到對多個字段的排序筒饰。pandas里,dataframe的多字段排序需要用by指定排序字段壁晒,SQL只要將多個字段依次卸載order by之后即可瓷们。例如,輸出uid秒咐,訂單數(shù)谬晕,訂單金額三列,并按照uid降序携取,訂單金額升序排列攒钳。(點擊圖片可以查看大圖)
在pandas中可能有一些細節(jié)需要注意,比如我們將聚合結(jié)果先賦值雷滋,然后重命名不撑,并指定了inplace=True替換原來的命名,最后才進行排序晤斩,這樣寫雖然有點繞焕檬,但整體思路比較清晰。
10.case when 操作
相比于其他操作尸昧,case when 操作可能不是那么“通用”揩页。它更常見于SQL場景中,可能會用于分組烹俗,可能會用于賦值,也可能用于其他場景萍程。分組幢妄,比如按照一定的分?jǐn)?shù)區(qū)間分成優(yōu)良中差。賦值茫负,比如當(dāng)數(shù)值小于0時蕉鸳,按照0計算。我們來舉例看一下分組的場景。將每個uid按照總金額分為[0-300)潮尝,[300,600),[600,900)榕吼,三組。分別用pandas和SQL實現(xiàn)如下勉失,注意這里我們的基礎(chǔ)數(shù)據(jù)是上一步的order_df羹蚣,SQL中也需要用子查詢來實現(xiàn)。(點擊圖片可以查看大圖)
熟悉pandas的朋友應(yīng)該能想到乱凿,pandas的這種分組操作有一種專門的術(shù)語叫“分箱”顽素,相應(yīng)的函數(shù)為cut,qcut,能實現(xiàn)同樣的效果徒蟆。為了保持和SQL操作的一致性胁出,此處采用了map函數(shù)的方式。您可以自己查閱資料了解另外的實現(xiàn)方式段审。
11.更新和刪除操作
更新和刪除都是要改變原有數(shù)據(jù)的操作全蝶。對于更新操作,操作的邏輯是:先選出需要更新的目標(biāo)行寺枉,再進行更新抑淫。pandas中,可以使用前文提到的方式進行選擇操作型凳,之后可以直接對目標(biāo)列進行賦值丈冬,SQL中需要使用update關(guān)鍵字進行表的更新。示例如下:將年齡小于20的用戶年齡改為20甘畅。(點擊圖片可以查看大圖)
刪除操作可以細分為刪除行的操作和刪除列的操作埂蕊。對于刪除行操作,pandas的刪除行可以轉(zhuǎn)換為選擇不符合條件進行操作疏唾。SQL需要使用delete關(guān)鍵字蓄氧。例如刪除年齡為30歲的用戶:(點擊圖片可以查看大圖)
對于刪除列的操作。pandas需要使用drop方法槐脏。SQL也需要使用drop關(guān)鍵字喉童。(點擊圖片可以查看大圖)
總結(jié):
簡單粗暴,小結(jié)如下圖所示:
reference:
https://pandas.pydata.org/pandas-docs/stable/getting_started/comparison/comparison_with_sql.html
https://juejin.im/post/5b5e5b2ee51d4517df1510c7
需要說明的是顿天,pandas和SQL是兩種不同的工具堂氯,本文進行比較并不想說明孰優(yōu)孰劣,只是為了對于二者的類似操作加深理解牌废,從而方便實際工作中更高效的使用二者咽白。實際工作中的操作可能比本文涉及到的復(fù)雜很多,甚至?xí)卸喾N組合的方式出現(xiàn)鸟缕,也可能會有本文沒有提及的情況晶框。但我們掌握了本文的方法排抬,就可以以不變應(yīng)萬變,遇到復(fù)雜情況也可從容應(yīng)對了授段,希望對你有所幫助蹲蒲!公眾號后臺回復(fù)“對比”可以獲得本次聯(lián)系的數(shù)據(jù)樣例以及文章清晰PDF版本,您可自行進行練習(xí)侵贵。
推薦閱讀:
左手pandas右手Excel届搁,帶你學(xué)習(xí)數(shù)據(jù)透視表