為了統計重復項,我將用戶的數據放在壹個列表中,然後使用len(set(data))來統計重復項。壹開始我以為這裏的數據量不大,每個用戶的數據不會超過100。我沒有註意到有些用戶會有幾萬條數據,所以消耗了很多時間(其實我的腳本最耗時的地方是因為從遠程redis取大量數據時的長時間阻塞,甚至連接超時。最後我采用了分而治之的方法,壹次取少量數據,性能提升很大)。
為了優化,我開始尋找高效的方法。我發現有大量的人認為使用字典會更有效率,即:
data_unique = {}。fromkeys(數據)。keys() len(data_unique)
所以,我做了壹個測試:
In[1]:import random In[2]:data =[random . randint(0,10000)for _ In xrange(1000000)]In[3]:% time it len(set(data))10個循環,best of 3: 39.7 ms每循環In [4]: %timeit len({}。fromkeys(數據)。keys()) 10次循環,每次循環3: 43.5毫秒
可以看出,使用字典的性能和使用集合的性能差不多,甚至可能更慢。
其實Python中有很多高效的庫,比如用numpy和pandas處理數據,性能接近C語言。然後,我們用numpy和熊貓來解決這個問題。在這裏,我還比較了獲取重復數據刪除數據的性能。代碼如下:
導入集合導入隨機as py_random導入timeit導入numpy.random as np_random導入熊貓as PD DATA _ SIZE = 1000000 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(100,size=DATA_SIZEseries(DATA)DATA _ unique = DATA . value _ counts()DATA _ unique . SIZE def py _ count():DATA =[py _ random . randint(0,1000)for _ in xrange(DATA _ SIZE)]集合。counter(DATA)def PD _ count():DATA = NP _ random . randint(1000,size=DATA_SIZE) data = pd。series(data)data . value _ counts()#腳本從此處開始if _ _ name _ _ = = " _ _ main _ _ ":t 1 = time it。Timer("py_cal_len()",setup = " from _ _ main _ _ import py _ cal _ len ")T2 = time it。Timer("pd_cal_len()",setup = " from _ _ main _ _ import PD _ cal _ len ")T3 = time it。Timer("py_count()",setup = " from _ _ main _ _ import py _ count ")T4 = time it。Timer("pd_count()",setup = " from _ _ main _ _ import PD _ count ")print t 1 . 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
使用熊貓統計的消重和消重數據,其性能是Python原生函數的10倍以上。