各位老鐵好,我是程序媛阿芳,來自南方一個山清水秀的地方,現在在北京中廠做一名北漂,每天要學習和處理很多事情,今天我回顧了下自己做過數據處理的一點經驗,和各位分享下經驗sql子查詢進行比較,希望更多老鐵關注、轉發和交流。
目前在數據處理分析和AI中得到了廣泛應用,但Sql作為傳統數據統計分析編程語言在日常數據提取分析、ETL開發和后臺存儲過程開發中主要用到。由于豐富的類庫使其在數據挖掘、機器學習等方面用得十分廣泛,基本將java在這一領域剔出,同時由于其自帶數值科學計算和Numpy等包的特性,在數據處理分析領域也是小露鋒芒,應用的越來越廣,這樣也與Sql有了交集。
由于目前實際工作中,開發模式的單一和循規蹈矩,另外傳統上也有個誤區,認為搞數倉和報表就是寫Sql,只有搞機器學習和人工智能的才用,其實關鍵看是否適合和好用,擇其優點用之。本篇我結合實際工作場景,嘗試系統性總結分析和比較兩者在數據處理分析中的應用,其中若有不當,還請各位老鐵指正,也歡迎各路大咖一起加入討論,以向更多從業者提供有價值參考。
是既面向對象又是過程性的語言,可以定義類和方法,數據結構也遠比Sql復雜,有元素、列表、字典、元組和集合,而Sql的設計思想是一切皆關系,這個關系就是二維表(Table),由行(Row)和列()組成,Sql就是圍繞這個關系表組成的集合進行操作。當然Sql在存儲過程中也可以定義函數,但此函數非函數能比,只能作為參數傳入,而函數是可以傳入對象,由于數據結構更豐富,可實現功能上要強大的多。數據處理和分析是一個基于業務實際場景需求對數據進行操作的過程,常見的有數倉的ETL(即對關系數據的抽取、合并轉換和數據不同分層的載入)、指標的統計即針對數據集的聚合計算、數據的預處理即對空值的填充和異常值的剔除等。下面針對實際應用場景做一些比較分析,也希望有同樣思考的志同道合者一起討論。
集合關聯操作:
數據分析需要比較和組合不同的數據集生成新的數據集,SQL中提供了大量的集合操作符支持上述需求。集合操作符支持對比性操作,可有條件連接數據集。SQL集合操作符包括UNION、UNION ALL、和(或者MINUS),是返回位于兩個待比較的查詢結果集中行,(或者MINUS)返回到非待比較的查詢語句結果集中的行。中和對象為二維表格數據集,通過等函數可實現集合關聯操作。
如需要將商品購買和出售用戶進行重復與并集合并,Sql示例如下:
-- SQL實現
from .
union all
from .
在中,可使用.()函數實現上邊重復合并集合操作,沿選定軸連接或。
# 實現
users = pd.([, ])
上邊為重復合并,要實現并集合并只需要中.()函數對應Sql中UNION即可。如果進一步想做交集,分析既是商品買家又是賣家的用戶,則中.merge()方法對應Sql中操作符就可以。
集合聚合操作:
Sql的聚合函數如sum()、avg()、count()、max()和min()等,只能用在和group by、子句的組合中,group by分組后聚合函數可以作用于每一個組,對每一個組的數據做一些統計。中的()函數+agg()函數可以實現聚合統計功能。如統計不同店鋪不同產品的月銷售量
#實現
.([‘’,‘’,‘’]).agg({‘’:‘sum’})
總結思考:
兩者的優劣如何并且在實際中怎么選擇呢?代碼實現簡單,Sql則要寫一大堆,如果遇到篩選很多字段的情況,則經常出現sql腳本很多行的情況,再加上后續會還有各種關聯會讓人看的眼花繚亂。但是存儲數據集有內存開銷,再加上目前結合Sql的Hive可以實現分布式計算,性能上是比強大很多的,上億的交易表都可以實現聚合分析,這也是目前在數倉和報表數據處理分析中仍然Sql為主的重要原因。但不是沒有可以發揮的余地,在數據量不是特別大,另外如果是的框架也部署在分布式環境,資源分配足夠的情況下也是可以使用的,因為隨著版本的升級,底層基本都用C++來重構實現,以解決計算時性能問題。當然這里考慮到成本和Sql已經支持的好的情況則沒有必要用,但是如果是進一步做一些數據的治理,例如空值NAN(數據庫中為null)值的填充替換或者一些校驗的話,則更為有優勢。如下圖部分NAN值的替換。
Sql要實現上述功能比較麻煩,首先定位到數據問題的行sql子查詢進行比較,再和其它數據連接合并起來,但就不需要了,直接一個()函數搞定。
#示例
= df1[3].(0.0);
在數據處理分析真正強大之處在于可以實現Sql所不能的地方,如需要對要分組的條件歸并后再對數值按照歸并后的組進行聚合統計。對于歸屬不同門店不同小微企業所有產品月購買金額的統計,因為門店與購買企業,每個購買企業對應產品都是不確定的,無法用sql實現篩選統計,但可以合并分組條件,計算金額,然后重新連接成一個數據集。
#示例
=.(['date','',',''])['prod'].apply( x: '|'.join(x[:]))
=.()
=.(['date','',',''])['amt'].sum()
=.()
=pd.([,['amt']],axis=1
此外在數據校驗方面,可直接對數據集使用函數或自定義函數判斷,不像Sql需要按條件去尋找和定位,限制了靈活發揮的空間。隨著數據應用的擴展和深入和各公司基礎技術開發平臺的日益完善,相信在數倉數據開發和運維、數據治理和報表智能化等場景中會發揮越來越大的作用,不再是算法工程師的御用語言。