计算python集合中的值的平均值。计数器

时间:2015-11-13 14:40:23

标签: python numpy

我分析了一些非常密切聚类的数字时间测量。我想获得平均值,标准偏差等。有些输入很大,所以我想我可以避免创建数百万个数字的列表而是 使用Python collections.Counter对象作为紧凑表示。

示例:我的一个小输入产生collection.Counter,如[(48, 4082), (49, 1146)],这意味着值48的4,082次出现和值49的1,146次出现。对于此数据集,我手动计算平均值为类似于48.2192042846。

当然,如果我有一个4,082 + 1,146 = 5,228个整数的简单列表,我会把它提供给numpy.mean()。

我的问题:如何根据collections.Counter对象中的值计算描述性统计信息,就像我有一个数字列表一样?我是否必须创建完整列表或是否有快捷方式?

3 个答案:

答案 0 :(得分:6)

collections.Counter()dict的子类。只需使用Counter().values()获取计数列表:

counts = Counter(some_iterable_to_be_counted)
mean = numpy.mean(counts.values())

请注意,我在此处调用Counter.most_common(),这将生成您在问题中发布的(key, count)元组列表。

如果您必须使用Counter.most_common()的输出,则可以使用列表理解过滤掉计数:

mean = numpy.mean([count for key, count in most_common_list])

如果您使用的是Python 3(其中dict.values()返回字典视图),您可以传入list(counts.values()),也可以使用标准库staticstics.mean() function,这需要一个可迭代的(包括dict.values()字典视图)。

如果您打算计算平均键值按其计数加权,您可以直接从计数器值进行自己的计算。在Python 2中,它是:

from __future__ import division

mean = sum(key * count for key, count in counter.iteritems()) / sum(counter.itervalues())

from __future__导入应位于模块的顶部,并确保您不会遇到大浮点数的溢出问题。在Python 3中,它将被简化为:

mean = sum(key * count for key, count in counter.items()) / sum(counter.values())

中位数可以用二分法计算;按键对(key, count)对进行排序,对计数求和,并将中间点平分为计数的累计和。插入点的索引指向排序键列表中的中间键。

答案 1 :(得分:3)

虽然您可以在创建值列表后将所有内容卸载到numpy,但这比所需要的要慢。相反,您可以使用您需要的实际定义。

均值只是所有数字的总和除以它们的数量,因此非常简单:

sum_of_numbers = sum(number*count for number, count in counter)
count = sum(count for n, count in counter)
mean = sum_of_numbers / count

标准偏差有点复杂。它是方差的平方根,方差又定义为"平方均值减去均值的平方"为您的收藏。 SOOOO ...

total_squares = sum(number*number * count for number, count in counter)
mean_of_squares = total_squares / count
variance = mean_of_squares - mean * mean
std_dev = math.sqrt(variance)

稍微多一些手动工作,但如果数字集有很多重复,也应该快得多。

答案 2 :(得分:0)

除非您想编写自己的统计函数,否则没有prêt-à-porter解决方案(据我所知)。

所以最后你需要创建列表,最快的方法是使用numpy。一种方法是:

import numpy as np

# One memory allocation will be considerably faster
# if you have multiple discrete values.
elements = np.ones(48+49)
elements[0:48] *= 4082
elements[48:] *= 1146

# Then you can use numpy statistical functions to calculate
np.mean(elements)
np.std(elements)
# ... 

更新:从现有collections.Counter()对象创建元素

c = collections.Counter({48: 4082, 49: 1146})
elements = np.ones(sum(c.values()))
idx = 0
for value, occurrences in c.iteritems():
    elements[idx:idx + occurrences] *= value
    idx += occurrences