设为首页 收藏本站
查看: 803|回复: 0

[经验分享] Python:使用Counter进行计数统计

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2016-9-12 09:13:12 | 显示全部楼层 |阅读模式
  计数统计就是统计某一项出现的次数。实际应用中很多需求需要用到这个模型。比如测试样本中某一指出现的次数、日志分析中某一消息出现的频率等等‘这种类似的需求有很多实现方法。下面就列举几条。
(1)使用dict
看下面代码

1
2
3
4
5
6
7
8
9
10
#coding=utf-8
data = ['a','2',2,4,5,'2','b',4,7,'a',5,'d','a','z']
count_frq = dict()
for one in data:
     if one in count_frq:
          count_frq[one] += 1
     else:
          count_frq[one] = 1

print count_frq



输出结果如下:

{'a': 3, 2: 1, 'b': 1, 4: 2, 5: 2, 7: 1, '2': 2, 'z': 1, 'd': 1}
这种方法最简单,也是最容易想到的,鄙人这写这篇博文之前用的最多,不过以后应该不会用来,我们应该使代码更加Pythonic
(2)使用set和list
代码如下:

1
2
3
4
5
6
7
8
#coding=utf-8
data = ['a','2',2,4,5,'2','b',4,7,'a',5,'d','a','z']
data_set = set(data)
count_list = []
for one in data_set:
     count_list.append((one,data.count(one)))

print count_list



输出结果如下:
[('a', 3), (2, 1), ('b', 1), (4, 2), (5, 2), (7, 1), ('2', 2), ('z', 1), ('d', 1)]
    这里面利用了list的通用方法和集合(set)的特性,集合是一个无序不重复的元素集,而工厂函数set()可以将列表转换为一个无序不重复的元素集合。

以上方法都很简单,但不够Pythonic。下面来介绍collections中的Counter类。
(一)Counter类
    Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)支持集合操作+、-、&、|,其中&、|操作分别返回两个Counter对象各元素的最大值和最小值。
(1)Counter的初始化
跟平时自定义类的初始化方法差不多,如下:

c = Counter("hello world")#可迭代对象创建

c = Counter(h=1,l=3,o=2)#关键字创建
c = Counter({'h':1,'l':3,'o':2})#字典创建
c = Counter()#空Counter类
(2)Counter类常见方法
elements():返回一个迭代器。元素被重复了多少次,在该迭代器中就包含多少个该元素。所有元素按照字母序排序,个数小于1的元素不被包含。
update():用于统计对象元素的更新,原有的Counter计数器对象与新增元素的统计计数值相加而不是直接替换。

subtract():该方法用于计数器对象中元素统计值减少,输入输出的统计值书可以为0或者负数的。
most_common([n]):可以查找出前n个出现频率最高的元素以及它们对于的次数,也就是说频率搞的排在最前面。
copy():浅拷贝。
所以上面的例子用Counter类的话,也很简单,代码如下:

1
2
3
4
5
#coding=utf-8
from collections import Counter
data = ['a','2',2,4,5,'2','b',4,7,'a',5,'d','a','z']
c = Counter(data)
print c



输出结果如下:
Counter({'a': 3, 4: 2, 5: 2, '2': 2, 2: 1, 'b': 1, 7: 1, 'z': 1, 'd': 1})
咱们接着看代码

1
2
print c.elements()
print list(c.elements())



输出结果如下:
<itertools.chain object at 0x7f94b81683d0>
['a', 'a', 'a', 2, 'b', 4, 4, 5, 5, 7, '2', '2', 'z', 'd']
1
2
3
4
c['z'] -= 1
print c
print c.elements()
print list(c.elements())



输出结果如下:

Counter({'a': 3, 4: 2, 5: 2, '2': 2, 2: 1, 'b': 1, 7: 1, 'd': 1, 'z': 0})
<itertools.chain object at 0x7f0e928723d0>
['a', 'a', 'a', 2, 'b', 4, 4, 5, 5, 7, '2', '2', 'd']
元素’z'的统计值变为了0,然后进行elements()运算后,‘z'就被排除掉了。
1
2
c.update("aaaa")
print c



输出结果:
Counter({'a': 7, 4: 2, 5: 2, '2': 2, 2: 1, 'b': 1, 7: 1, 'd': 1, 'z': 0})
update()在原基础上增加了计数值
1
2
c.subtract("aaaaa")
print c



输出结果如下:
Counter({'a': 2, 4: 2, 5: 2, '2': 2, 2: 1, 'b': 1, 7: 1, 'd': 1, 'z': 0})
subtract()在原基础上减少计数值
1
print c.most_common()



输出结果如下:
[('a', 2), (4, 2), (5, 2), ('2', 2), (2, 1), ('b', 1), (7, 1), ('d', 1), ('z', 0)]
以上代码都是连接在一起的。
(3)算术和集合操作
1
2
3
4
5
6
7
8
9
10
11
#coding=utf-8
from collections import Counter
data = ['a','2','2','b','a','d','a',]
c = Counter(data)
b = Counter(a=1,b=2)
print c
print b
print b+c  # c[x] + d[x]
print c-b   # subtract(只保留正数计数的元素)
print c&b   # 交集:  min(c[x], d[x])
print c|b    # 并集:  max(c[x], d[x])



输出结果如下:
Counter({'a': 3, '2': 2, 'b': 1, 'd': 1})
Counter({'b': 2, 'a': 1})
Counter({'a': 4, 'b': 3, '2': 2, 'd': 1})
Counter({'a': 2, '2': 2, 'd': 1})
Counter({'a': 1, 'b': 1})
Counter({'a': 3, '2': 2, 'b': 2, 'd': 1})

(4)其它
Counter类返回值跟字典很类似,所以字典类的方法对Counter对象也适用。如下:
1
2
3
4
5
6
7
8
9
10
11
#coding=utf-8
from collections import Counter
data = ['a','2',2,4,5,'2','b',4,7,'a',5,'d','a','z']
c = Counter(data)
print c.keys()
print c.has_key('a')
print c.get('a')
print c.items()
print c.values()
print c.viewitems()
print c.viewkeys()



输出如下:
['a', 2, 'b', 4, 5, 7, '2', 'z', 'd']
True
3
[('a', 3), (2, 1), ('b', 1), (4, 2), (5, 2), (7, 1), ('2', 2), ('z', 1), ('d', 1)]
[3, 1, 1, 2, 2, 1, 2, 1, 1]
dict_items([('a', 3), (2, 1), ('b', 1), (4, 2), (5, 2), (7, 1), ('2', 2), ('z', 1), ('d', 1)])
dict_keys(['a', 2, 'b', 4, 5, 7, '2', 'z', 'd'])
这只是其中一部分,其它的方法可以参考字典类的方法。
另外,Counter对象还支持工厂函数操作set()、list()、dict().
有时间再补充介绍collections模块中其它的类



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-271019-1-1.html 上篇帖子: CentOS 6.5安装python3.3.4 下篇帖子: python中super出现的TypeError: must be type, not classobj 原因及解决
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表