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

irlmq6kh  于 2023-10-19  发布在  Python
关注(0)|答案(3)|浏览(92)

我在分析一些非常密集的数字时间测量。我想得到平均值、标准差等。有些输入很大,所以我想我可以避免创建数百万个数字的列表,而是使用Python集合。计数器对象作为紧凑的表示。
例如:我的一个小输入产生了一个类似[(48, 4082), (49, 1146)]collection.Counter,这意味着值48出现了4,082次,值49出现了1,146次。对于这个数据集,我手动计算平均值为48.2192042846。
当然,如果我有一个简单的4,082 + 1,146 = 5,228个整数的列表,我只需要将其提供给numpy.mean()。
我的问题是:如何从collections.Counter对象中的值计算描述性统计数据,就像我有一个数字列表一样?我必须创建完整的列表还是有快捷方式?

uqcuzwp8

uqcuzwp81#

collections.Counter()dict的子类。只需使用Counter().values()来获取计数列表,您可以使用标准库staticstics.mean()函数

import statistics

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

请注意,我没有在这里调用Counter.most_common(),这将生成您在问题中发布的(key, count)元组列表。
如果必须使用Counter.most_common()的输出,可以使用生成器表达式过滤掉计数:

mean = statistics.mean(count for key, count in most_common_list)

如果你想计算平均值 key value,并通过它们的计数进行加权,你可以直接从计数器值中进行自己的计算:

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

注意:我在这里使用了Counter.total(),这是Python 3.10中的新特性。在旧版本中。使用sum(counter.values())
对于中位数,使用statistics.median()

import statistics

counts = Counter(some_iterable_to_be_counted)
median = statistics.median(counts.elements())

或者,对于key * value

median = statistics.median(key * count for key, count in counts.items())
ttygqcqt

ttygqcqt2#

虽然您可以在创建一个值列表后将所有内容卸载到numpy,但这将比所需的速度慢。相反,您可以使用您需要的实际定义。
平均值就是所有数字的总和除以它们的计数,所以这很简单:

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

标准差稍微复杂一点。它是方差的平方根,而方差又被定义为集合的“平方均值减去均值的平方”。苏...

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)

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

ejk8hzay

ejk8hzay3#

除非你想写自己的统计函数,否则没有现成的解决方案(据我所知)。
所以最后你需要创建列表,最快的方法是使用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)
# ...

UPDATE:从现有的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

相关问题