文件數據去重示例

在數據處理業務中,有時需要清除文件中的重複數據或只留下重複數據,本文將從小文件、大文件兩方面介紹整行去重、關鍵列去重的幾種處理辦法,並提供用 esProc SPL 編寫的代碼示例。esProc 是專業的數據計算引擎,SPL 中有一套完善的集合運算領域的函數庫,很適合處理文件去重,寫出的代碼非常簡潔。

 

1.   小文件

1.1  整行去重

有一個文本文件,其每一行是一個字符串,要將文件中的重複行只保留一行。處理此問題可以把文件的每一行讀成一個字符串,組成一個集合,然後通過集合去重運算得出結果。

示例:報名繪畫興趣班的同學學號姓名記錄在paint.txt中,可能有些同學報了多次,請刪除文件中重複的報名後保存在paint1.txt中。原文件部分數據如下所示
    20121102-Joan
    20121107-Jack
    20121113-Mike
    20121107-Jack



esProc SPL腳本如下:


A 註釋
1 =file("e:/txt/paint.txt").read@n() 讀出paint.txt的每一行組成集合
2 =A1.id() 刪除A1集合中重複的成員
3 =file("e:/txt/paint1.txt").write(A2) 將刪除重複行後的A2寫入文件paint1.txt中

 

1.2  關鍵列比較

一個文件,有多列數據,第一行是列名,第二行開始是數據記錄,要對文件中關鍵列的內容進行比較,對關鍵列內容重複的行進行刪除或只保留重複的行。

現有2018年的銷售訂單表order_2018.xlsx,部分數據如下所示:

    ..

 

1.2.1.  去除重複

示例1:請求出2018年購買產品的所有不同的客戶Id,保存在文件2018c.xlsx中。

esProc SPL腳本如下:


A 註釋
1 =file("e:/txt/order_2018.xlsx").xlsimport@t() 讀出2018訂單表數據
2 =A1.id(CustomerId) 取出所有不重複的客戶 Id
3 =file("e:/txt/2018c.xlsx").xlsexport(A2) 將客戶Id保存到文件2018c.xlsx

 

示例2:請求出2018年各位客戶購買了哪些不同產品,將CustomerId和ProductId保存在文件2018c_p.xlsx中。

esProc SPL腳本如下:


A 註釋
1 =file("e:/txt/order_2018.xlsx").xlsimport@t(CustomerId,ProductId) 讀出2018訂單表關鍵列數據
2 =A1.group@1(CustomerId,ProductId) 按關鍵列分組,@1表示只取分組中的一條記錄
3 =file("e:/txt/2018c_p.xlsx").xlsexport@t(A2) 將結果A2保存到文件2018c_p.xlsx

 

1.2.2.   只保留重複

示例:請求出2018年回頭客(即多次購買同種產品的客戶)的訂單情況,將結果保存在文件2018c_rebuy.xlsx中。

esProc SPL腳本如下:


A 註釋
1 =file("e:/txt/order_2018.xlsx").xlsimport@t() 讀出2018訂單表數據
2 =A1.group(CustomerId,ProductId) 同一客戶購買同種產品的訂單分爲一組
3 =A2.select(~.count()>1).conj() 選出訂單數大於1的組,把各組的訂單並集爲一個數據表
4 =file("e:/txt/2018c_rebuy.xlsx").xlsexport@t(A3) 將結果A3保存到文件2018c_rebuy.xlsx

 

 

2.  大文件

大文件數據不能一次性全部裝進內存,不能象小文件數據那樣全部讀出來再進行重複性比較,需要分批讀出數據去比較。esProc SPL提供了遊標來處理大文件運算,使大文件去重運算也變得十分方便。

2.1  整行去重

有大文本文件,其每一行是一個字符串,要將文件中的重複行只保留一行。處理此問題要把文件的每一行讀成一個字符串,成爲遊標中的一條記錄,然後通過遊標的去重運算得出結果。

示例:現有全國房產產權人員登記表大文件all.txt,裏面記錄產權人的身份證及姓名,部分數據如下所示:
    510121198802213364-Joan
    110113199203259852-Jack
    201264197206271113-Mike


由於有些人員在多個州擁有房產,所以文件中會有重複的登記,請將重複的登記只保留一個,將結果保存在all2.txt中。esProc SPL腳本如下:


A 註釋
1 =file("e:/txt/all.txt").cursor@s() 創建遊標,@s表示用整行構成單字段串的序表
2 =A1.groupx(_1) 對遊標中的單字段分組,就可去掉重複的行
3 =file("e:/txt/all2.txt").export(A2) 將去重後的結果寫入文件all2.txt中

 

2.2  關鍵列比對

本節仍用銷售訂單表爲例,是所有年份的合併銷售訂單表orders.xlsx,是個大文件。

2.2.1.   去除重複

示例1:請找出購買產品的所有不同的客戶Id,保存在文件customers.xlsx中。

esProc SPL腳本如下:


A 註釋
1 =file("e:/txt/orders.xlsx").xlsimport@tc() 創建訂單表數據遊標
2 =A1.groupx(CustomerId) 按CustomerId分組即得到不重複的客戶Id
3 =file("e:/txt/customers.xlsx").xlsexport@t(A2) 將客戶Id保存到文件customers.xlsx

 

示例2:請找出各位客戶購買了哪些不同產品,將CustomerId和ProductId保存在文件c_p.xlsx中。

esProc SPL腳本如下:


A 註釋
1 =file("e:/txt/orders.xlsx").xlsimport@tc() 創建訂單表數據遊標
2 =A1.groupx(CustomerId,ProductId) 按關鍵列分組,即可取得不重複的客戶Id和產品Id
3 =file("e:/txt/c_p.xlsx").xlsexport@t(A2) 將結果A2保存到文件c_p.xlsx

 

2.2.2.   只保留重複

示例:請找出回頭客(即多次購買同種產品的客戶)的訂單情況,將結果保存在文件c_rebuy.xlsx中。

esProc SPL腳本如下:


A 註釋
1 =file("e:/txt/orders.xlsx").xlsimport@tc().sortx(CustomerId,ProductId) 創建訂單表數據遊標,並按關鍵列排序
2 =A1.group(CustomerId,ProductId) 同一客戶購買同種產品的訂單分爲一組
3 =A2.select(~.count()>1).conj() 選出訂單數大於1的組,把各組的訂單並集爲一個數據表
4 =file("e:/txt/c_rebuy.xlsx").xlsexport@t(A3) 將結果A3保存到文件c_rebuy.xlsx

 《SPL CookBook》中還有更多相關計算示例。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章