Python 快速統計數據的去重數和去重數據


之前用 Python 寫過一個腳本,用來處理上千萬用戶的一些數據,其中有一個需求是統計用戶的某一數據的去重數量。為了加快程序的速度,我啟用了多進程。但不幸的是,程序跑了近一個星期,還沒處理完。這時,我感覺到了不對,於是開始查看程序的性能瓶頸。

對於統計去重數,我是將用戶的數據放到一個列表中,然后用 len(set(data)) 去統計去重數量。剛開始我以為這的數據量並不大,每個用戶的數據不會過百,我並沒有注意到有的用戶會有上萬條的數據,因此消耗了大量的時間(其實我的腳本消耗時間最大的地方是因為從遠程 redis 中取大量數據時發生長時間的阻塞,甚至連接超時,最后我采用的方式分而治之,每次取少量的數據,這樣大大的提高了性能)。

為了做優化,我開始尋求高效的方法。我發現,有大量的人認為采用字典效率會更高,即:

data_unique = {}.fromkeys(data).keys()
len(data_unique)
歡迎加入我的QQ群`923414804`與我一起學習,群里有我學習過程中整理的大量學習資料。加群即可免費獲取

於是,我做了下測試:

In [1]: import random

In [2]: data = [random.randint(0, 1000) for _ in xrange(1000000)]

In [3]: %timeit len(set(data))
10 loops, best of 3: 39.7 ms per loop

In [4]: %timeit len({}.fromkeys(data).keys())
10 loops, best of 3: 43.5 ms per loop

由此可見,采用字典和采用集合的性能是差不多的,甚至可能還要慢些。

在 Python 中其實有很多高效的庫,例如用 numpy、pandas 來處理數據,其性能接近於 C 語言。那么,我們就用 numpy 和 pandas 來解決這個問題,這里我還比較了獲取去重數據的性能,代碼如下:

import collections
import random as py_random
import timeit

import numpy.random as np_random
import pandas as pd

DATA_SIZE = 10000000

def py_cal_len():
    data = [py_random.randint(0, 1000) for _ in xrange(DATA_SIZE)]
    len(set(data))

def pd_cal_len():
    data = np_random.randint(1000, size=DATA_SIZE)
    data = pd.Series(data)
    data_unique = data.value_counts()
    data_unique.size

def py_count():
    data = [py_random.randint(0, 1000) for _ in xrange(DATA_SIZE)]
    collections.Counter(data)

def pd_count():
    data = np_random.randint(1000, size=DATA_SIZE)
    data = pd.Series(data)
    data.value_counts()

# Script starts from here

if __name__ == "__main__":
    t1 = timeit.Timer("py_cal_len()", setup="from __main__ import py_cal_len")
    t2 = timeit.Timer("pd_cal_len()", setup="from __main__ import pd_cal_len")
    t3 = timeit.Timer("py_count()", setup="from __main__ import py_count")
    t4 = timeit.Timer("pd_count()", setup="from __main__ import pd_count")

    print t1.timeit(number=1)
    print t2.timeit(number=1)
    print t3.timeit(number=1)
    print t4.timeit(number=1)

運行結果:

12.438587904
0.435907125473
14.6431810856
0.258564949036

利用 pandas 統計數據的去重數和去重數據,其性能是 Python 原生函數的 10 倍以上。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM