一場pandas與SQL的巔峰大戰(zhàn)(一)

作為一名數(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封寞,訂單金額。

image

我們將用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ù)庫魂莫。

image

開始學(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é)果如下:(點擊圖片可以查看大圖)

image

如果只想查看前10行數(shù)據(jù)呢。pandas可以調(diào)用head(n)方法山卦,n是行數(shù)鞋邑。MySQL可以使用limit n,n同樣表示行數(shù)账蓉。(點擊圖片可以查看大圖)

image

2.查詢特定列的數(shù)據(jù)

有的時候我們只想查看某幾列的數(shù)據(jù)枚碗。在pandas里可以使用中括號或者loc,iloc等多種方式進行列選擇铸本,可以選擇一列或多列肮雨。loc方式可以直接寫列名,iloc方式需要指定索引箱玷,即第幾列怨规。SQL里只需寫相應(yīng)的列名即可陌宿,舉例如下,實際操作一下更容易理解波丰,選擇一種自己習(xí)慣的即可限番。(點擊圖片可以查看大圖)

image
image

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ù)缤底。(點擊圖片可以查看大圖)

image

4.查詢帶有1個條件的數(shù)據(jù)

例如我們要查詢uid為10003的所有記錄。pandas需要使用布爾索引的方式番捂,而SQL中需要使用where關(guān)鍵字个唧。指定條件時,可以指定等值條件设预,也可以使用不等值條件徙歼,如大于小于等。但一定要注意數(shù)據(jù)類型鳖枕。例如如果uid是字符串類型魄梯,就需要將10003加引號,這里是整數(shù)類型所以不用加宾符。代碼如下:(點擊圖片可以查看大圖)

image

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有多少訂單量。兩種工具的操作如下:(點擊圖片可以查看大圖)

image

如果想要同時對不同的字段進行不同的聚合操作诺祸。例如目標(biāo)變成:求每個uid的訂單數(shù)量和訂單總金額携悯。寫法會稍微不同一些,如下圖所示序臂。(點擊圖片可以查看大圖)

image

更進一步的蚌卤,我們可以對結(jié)果的數(shù)據(jù)集進行重新命名。pandas可以使用rename方法奥秆,MySQL可以使用as 關(guān)鍵字進行結(jié)果的重命名。(點擊圖片可以查看大圖)

image

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ù)樣例如下所示映企。(點擊圖片可以查看大圖)

image
  • 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)不出左連接的特點,感興趣的讀者可以自己嘗試下宣蔚。(點擊圖片可以查看大圖)

image
  • 其他連接方式

    如果要實現(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í)行的代碼如下:(點擊圖片可以查看大圖)

image

以上是沒有去重的情況,如果想要去重免绿,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)的代碼可以參考下方:(點擊圖片可以查看大圖)

image

排序時婶希,asc表示升序,desc表示降序蓬衡,能看到兩種方法都指定了排序方式喻杈,原因是默認(rèn)是會按照升序排列。在此基礎(chǔ)上狰晚,可以做到對多個字段的排序筒饰。pandas里,dataframe的多字段排序需要用by指定排序字段壁晒,SQL只要將多個字段依次卸載order by之后即可瓷们。例如,輸出uid秒咐,訂單數(shù)谬晕,訂單金額三列,并按照uid降序携取,訂單金額升序排列攒钳。(點擊圖片可以查看大圖)

image

在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)。(點擊圖片可以查看大圖)

image

熟悉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甘畅。(點擊圖片可以查看大圖)

image

刪除操作可以細分為刪除行的操作和刪除列的操作埂蕊。對于刪除行操作,pandas的刪除行可以轉(zhuǎn)換為選擇不符合條件進行操作疏唾。SQL需要使用delete關(guān)鍵字蓄氧。例如刪除年齡為30歲的用戶:(點擊圖片可以查看大圖)

image

對于刪除列的操作。pandas需要使用drop方法槐脏。SQL也需要使用drop關(guān)鍵字喉童。(點擊圖片可以查看大圖)

image
總結(jié):

簡單粗暴,小結(jié)如下圖所示:

image

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ù)透視表

一次不算愉悅的爬蟲與可視化之旅

關(guān)于Left join,你可能不知道這些......

我所理解的互聯(lián)網(wǎng)數(shù)據(jù)分析師

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末模燥,一起剝皮案震驚了整個濱河市咖祭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蔫骂,老刑警劉巖么翰,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異辽旋,居然都是意外死亡浩嫌,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門补胚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來码耐,“玉大人,你說我怎么就攤上這事溶其∩龋” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵瓶逃,是天一觀的道長束铭。 經(jīng)常有香客問我,道長厢绝,這世上最難降的妖魔是什么契沫? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮昔汉,結(jié)果婚禮上懈万,老公的妹妹穿的比我還像新娘。我一直安慰自己靶病,他們只是感情好会通,可當(dāng)我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著娄周,像睡著了一般渴语。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上昆咽,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天,我揣著相機與錄音,去河邊找鬼掷酗。 笑死调违,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的泻轰。 我是一名探鬼主播技肩,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼浮声!你這毒婦竟也來了虚婿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤泳挥,失蹤者是張志新(化名)和其女友劉穎然痊,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體屉符,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡剧浸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了矗钟。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片唆香。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖吨艇,靈堂內(nèi)的尸體忽然破棺而出躬它,到底是詐尸還是另有隱情,我是刑警寧澤东涡,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布冯吓,位于F島的核電站,受9級特大地震影響软啼,放射性物質(zhì)發(fā)生泄漏桑谍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一祸挪、第九天 我趴在偏房一處隱蔽的房頂上張望锣披。 院中可真熱鬧,春花似錦贿条、人聲如沸雹仿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽胧辽。三九已至,卻和暖如春公黑,著一層夾襖步出監(jiān)牢的瞬間邑商,已是汗流浹背摄咆。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留人断,地道東北人吭从。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像恶迈,于是被迫代替她去往敵國和親涩金。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,697評論 2 351

推薦閱讀更多精彩內(nèi)容