Python處理海量手機號碼

來源:互聯網
上載者:User

標籤:

Python處理海量手機號碼一、任務描述

上周,老闆給我一個小任務:批量產生手機號碼並去重。給了我一個Excel表,裡面是中國移動各個地區的可用手機號碼前7位(如),裡面有十三張表,每個表裡的電話號碼首碼估計大概是八千個,需要這些7位號碼產生每個都產生後4位組成11位手機號碼,也就說每一個格子裡面的手機號碼都要產生一萬個手機號。而且還有,本來伺服器已經使用了一部分手機號碼了,要在產生的號碼列表裡去掉已經使用過的那一批。已經使用過的這一批號碼已經匯出到了一批txt文本裡,約4000w,每個txt有10w個號碼,裡面有重複的,老闆估計實際大概是3000w左右。老闆可以給我分配使用一個16G記憶體、8核CPU的Windows伺服器來跑程式。

二、任務分析

要處理海量資料,所以程式的執行效率和佔用記憶體不能太高,應該能在開發機的4G記憶體下也大概跑得動,即關掉所有編程IDE和伺服器軟體,只用Notepad++和瀏覽器(用來查資料)的情況下不會卡機。這次任務可能會用到的技術有:程式Excel的處理,檔案的遍曆和讀寫,大型數組的操作,多線程並發。預估任務完成周期:一周(日常工作正常進行的前提下)。

三、技術分析

PHP:很熟悉,但是執行效率和記憶體佔用不夠好,可能會卡機,要實現多線程似乎有點複雜。(有待斟酌)

Javascript:較熟悉,執行效率和記憶體佔用不太清楚,但是弱類型通常都比較堪憂,各種回調比較幹擾思維不順手。(不考慮)

Java:略懂,學起來和寫起來都比較麻煩,開發效率比較慢。(有待斟酌)

C#:沒用過,較難學(比JAVA易,比指令碼難)。(有待斟酌)

C/C++:略懂,數組處理、多線程這兩個似乎比較難搞。(不考慮)

Python:沒用過,據說很容易學,有個研究生同學用它來做物理運算等,執行效率應該不低。(試試看)

於是就打著試試看的心態,開啟了菜鳥教程(Runoob)的Python教程大概看了一下,目錄中有幾個數組(List、元組、字典)、檔案IO、File和多線程,看了一下常式果然好簡單。再度娘了一下python處理Excel,果斷簡單快捷!於是開啟了玩蛇之路。

四、合并(./4000w/hebing.py)

本文開頭說到,有4000w的已用號碼列表,但是裡面是有重複的,而後面的處理都需要用到這些號碼。而看到這400多個txt檔案加起來大小約500M,所以全部讀進去再進行處理也可以承受。所以先把這些檔案讀進去合并去重,輸出成為一個txt檔案。最後得到的號碼有1800w多條,輸出txt檔案大小約209M。

 hebing.py

其中對數組內的元素進行合并去重的那一句是 txtArr = list( set(txtArr) ) 。很神奇對吧,這兩個是什麼函數?其實這兩個都是轉換類型的函數。先把它轉換成了 set 類型,再轉換為 list 類型(列表/數組)。python的set(集合)類型是一個無序不重複的元素集,所以list轉換為set之後就自動去重了,當然同時順序也會被打亂了,不過這裡的順序不重要就不用管它啦。

最後數群組轉換為字串也是直接用字串拼接數組就轉換了,不要用for迴圈,非常非常耗時間的。

五、Excel處理(./preNum.py)

根據網上常式直接讀取Excel第一個表裡面的內容出來,合并成數組轉成字串存到文本裡面去。在轉成字串的時候發現報錯似乎是說資料類型不對,才知道原來python與PHP、JS不同,是強型別的=_=!於是先在Excel裡把表裡面的資料轉換成字串格式(excel裡準確叫文字格式設定),轉換後excel表裡面的資料格左上方是有綠色的小三角形的。每個表單獨處理產生一個檔案,一個檔案裡面大概有八千個手機號碼首碼。

 preNum.py六、組建編號碼並去掉已用過的

首先來想想,有十三個表,一個表裡面有大概八千個號碼首碼,每個首碼產生一萬個號碼,每個號碼要與前面所說的1800萬的已用手機號碼進行比對去重。你會怎麼做呢???

↓↓

↓↓

我的想法是,分成十三次來做,每次一個表,每個表中八千多個號碼,使用多線程,八千多個線程,每個線程產生一萬個號碼並與那1800萬個號碼一 一比對。

其中產生和去重的核心代碼如下,每產生一個號碼的時間大概是0.5秒。所以估計了一下時間,10000*0.5s ≈ 83min,八千個線程大概要一個半小時左右。

#這裡是重複的號碼#fileobj = open(‘testBugNum.txt‘);    #測試的fileobj = open(‘list-dataAll.txt‘);    #實際的bugTxtStr = fileobj.read();fileobj.close();bugTxtArr = bugTxtStr.splitlines();    #已用過的號碼的列表while j < 10000:    #產生一萬個同首碼號碼    newNum = str( int(txtNum)*10000+j );    j += 1;#        print newNum;    if not newNum in bugTxtArr:        #如果不在已用過的號碼列表裡        numArr.append( ‘+86‘+newNum );        print ‘+86‘+newNum;

我在本機大概運行了一下,觀察了幾分鐘,似乎線程建立得比較慢,有些已經跑到了十幾個了,有的才剛建立線程。線程調度嘛,不按照順序嘛,除了輸出很亂以外,似乎也沒有什麼其它問題。於是就上傳到伺服器上去跑了,然後再過了一會就下班回家了。第二天回到公司,連上伺服器看看,出乎意料啊,看到輸出的資訊裡面,那些線程才跑到 三百多,天呐什麼時候才能跑到一萬啊。而且還有坑爹的是,偶爾就看到有些線程建立失敗⊙o⊙

七、思考思考(./doData.py)

從前面的運行資訊來看,這裡使用多線程似乎並沒有加快程式的運行啊,這是為什麼呢?如果不能用多線程,那麼產生比對的地方就要改成另外更高效的方式了,有嗎?

第一問,從網上找到答案,確實說在計算密集型程式中,多線程比單線程更糟,因為一個CPU就那麼幾個核,不同的線程還是一樣要佔用CPU資源,再加上線程調度的時間和空間,真是天坑。第二問,PHP中有從一個數組去除另一個數組的函數(官方說法叫做數組的差集 array_diff() ),那麼python應該也會有這樣的函數,先成一萬個號碼的數組再進行差集 會不會比原來 每個號碼對比再合并效率快呢?

實踐了一下,證明確實效率高了極多極多,python中的數組差集是這個樣子的 numArr = list( set(numArr) - set(bugTxtArr) ) 測了一下,大概三秒完成一批號碼(一批約等於一萬個號碼),之前是半秒一個號碼\( ^▽^ )/。但也注意現在產生的一萬個號碼排序是亂的,因為中間轉換成的set類型是無序的,如果需要從小到大排序,那還要再加個函數排序一下,問了老闆說不用按順序,那就直接這樣了。

期間調試的時候發現,使用多線程有時會報錯 Unhandled exception in thread started by sys.excepthook is missing 之類的,網上查資料說是因為主進程已經執行完畢,那麼其建立的線程就會被關掉。所以我的做法就是讓主進程最後為一直執行空語句,很像當年用C語言做單片機的做法呢→_→雖然最後不用多線程了,直接單線程處理,安全穩定。

 doData.py八、合并整理(./hbData.py)

經過了大概六個小時的號碼產生,最後就是把一個Excel表產生的八千多個檔案整理,每十個檔案合成一個,每個檔案約十萬個號碼,每個號碼前面加上 “+86” 。就遍曆一下目錄,沒什麼技術點就不詳說了。

 hbData.py

後話,總共只有十三個表,這些程式稍微改一下,執行十三次就行了。值得注意的是,我這裡的程式幾乎每個都有一個全域變數 tblIndex, 是以防一檔案裡面一個個修改目錄名和檔案名稱,疏忽有可能導致的資料覆蓋。

總結
  1. 使用指令碼語言有一個很重要的要點:要盡量用語言提供的函數,不要自己實現演算法,尤其是迴圈的那種,執行速度不在一個數量級。
  2. 處理大批量的資料,要拆分步驟,產生中間檔案。大量資料複雜操作要小批量小批量地慢慢調試,結果無誤才逐步切換成真實資料。
  3. 多線程在運算密集型的情境中是沒有用武之處的,就算CPU是多核也沒什麼用,反而會造成順序隨機不易觀察,線程不穩定容易出錯,線程間切換記憶體消耗加大等弊端。
  4. 據說GPU可以用來挖礦、暴力破解等,對本情境這種高並發、簡單邏輯的運算應該也非常適用,以後可能要用得上GPU編程(求推薦教程)。

Python處理海量手機號碼

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.