[python][collections] Counter 計數器
在做文字統計分析的時候,我們經常會需要進行“計數”這樣一個環節。而如果直接使用字典,程式碼難免會變得複雜。其實, collections 模組中早就給我們定義好了 Counter 類,它可以很方便地實現計數的功能。
1. 建立一個 Counter 物件
只需要使用 Counter()
就可以建立一個 Counter 物件了,其中的引數可以有許多種寫法:
-
列表
Counter(['apple', 'boy', 'apple'])
-
字典
Counter({'apple':2, 'boy':1})
-
字串(每一個字元視為一個元素)
Counter('aabca')
-
關鍵字形式
Counter(apple=2, boy=1)
接下來以一個小例子對比一下使用普通的字典與 Counter 統計詞頻的區別。在統計之前,我們先對文字進行一些處理:
s = 'A boy and a girl'
s = s.lower().split()
切分完文字之後,我們先展示使用普通的字典進行詞頻統計的方法:
d = {}
for word in s:
if word in d:
d[word] += 1;
else:
d[word] = 1;
print(d)
{'a': 2, 'boy': 1, 'and': 1, 'girl': 1}
雖然 python 的語法已經比其他程式語言簡單不少,但是這樣的結構看起來還是有些繁瑣。而如果使用 Counter 物件的話,我們只需要用一行語句就可以完成:
c = Counter(s)
print(c)
Counter({'a': 2, 'boy': 1, 'and': 1, 'girl': 1})
可見, Counter 的確能夠簡化我們對計數的操作。不過除了能夠在一開始的統計上簡化程式碼外,它還有許多方便的方法可以使用。
2. 獲取對應鍵的值
Counter 獲取值的方法與字典類似,只需要用 [key]
就可以獲取對應的值。不過它與原先的字典不一樣的是,如果 key
不存在,它不會有 KeyError
的報錯,而是會返回 0
。
a = Counter('aabc')
print(a['d'])
0
在原先使用字典時,在查詢鍵之前,我們都需要先進行檢驗。而使用 Counter 型別就十分方便。
3. Counter 的加減
其實, Counter 裡面已經實現了對加減號的過載。它可以實現將兩個計數器裡面的對應值相加或相減。
a = Counter('aabc')
b = Counter('bbcd')
c = a + b
d = a - b
print(c)
print(d)
這段程式執行的結果如下:
Counter({'b': 3, 'a': 2, 'c': 2, 'd': 1})
Counter({'a': 2})
可以看到,當一個元素的計數被減至0時,它便不會再出現,而不需要單獨處理“個數為負”的情況。
不過,如果你想要負的結果,那麼你可以選擇 subtract()
方法。
a = Counter('aabc')
b = Counter('aaaa')
a.subtract(b)
print(a)
print(+a)
print(-a)
+a
與 -a
可以返回 Counter 中正的部分與負的部分(不過 -a
返回的負值的相反數)。這一個操作十分常用。
Counter({'b': 1, 'c': 1, 'a': -2})
Counter({'b': 1, 'c': 1})
Counter({'a': 2})
4. most_common() - 取出最多的 n 個元素
詞頻統計中,我們往往需要取出最大的幾個元素,用於後續的分析。而這項功能, Counter 也幫我們做好了。我們只需要呼叫 most_common(n)
方法,就可以取出 Counter 物件中最多的 n
個元素,並返回一個元組型別。
a = Counter('abracadabra')
print(a.most_common(3))
元組內的每一個元素都分別是對應的鍵值,並且已經按照降序排列:
[('a', 5), ('b', 2), ('r', 2)]
僅僅一行,我們就可以獲取 Counter 計數器中最多的幾項了,這極大的簡化了我們的程式碼量。
總結
上面的介紹展示了 Counter 計數器的常用方法。其實在瞭解它之前,我一直都是用字典做詞頻統計,因此也更發現 Counter 計數器在這一類問題上的簡便性。大家也可以嘗試一下自己用字典實現這一些功能,這樣便能夠更好地理解 Counter 的工作原理。