我正在尝试计算Python中值列表的模式(最常见的值)。我提出了一个解决方案,无论如何都给出了错误的答案,但后来我才意识到我的数据可能是短期的;
ie 1,1,2,3,4,4 mode = 1 & 4
这是我到目前为止所提出的:
def mode(valueList):
frequencies = {}
for value in valueList:
if value in frequencies:
frequencies[value] += 1
else:
frequencies[value] = 1
mode = max(frequencies.itervalues())
return mode
我认为这里的问题是我输出的值而不是最大值的指针。无论如何,任何人都可以建议一个更好的方法,这可以在有多个模式的情况下工作吗?或者没有说明我如何解决到目前为止我所得到的并确定单一模式?
你可能会说我对python很新,谢谢你的帮助。
编辑:应该提到我在Python 2.4中
答案 0 :(得分:5)
在Python> = 2.7中,对频率表使用collections.Counter
。
from collections import Counter
from itertools import takewhile
data = [1,1,2,3,4,4]
freq = Counter(data)
mostfreq = freq.most_common()
modes = list(takewhile(lambda x_f: x_f[1] == mostfreq[0][1], mostfreq))
请注意使用匿名函数(lambda
)来检查一对(_, f)
是否与最常用的元素具有相同的频率。
答案 1 :(得分:5)
嗯,第一个问题是肯定的,你在frequences
而不是密钥中返回值。这意味着您获得模式的计数,而不是模式本身。通常,要获得该模式,您可以使用key
关键字参数max,如下所示:
>>> max(frequencies, key=counts.get())
但在2.4中并不存在!以下是我认为可以在2.4中使用的方法:
>>> import random
>>> l = [random.randrange(0, 5) for _ in range(50)]
>>> frequencies = {}
>>> for i in l:
... frequencies[i] = frequencies.get(i, 0) + 1
...
>>> frequencies
{0: 11, 1: 13, 2: 8, 3: 8, 4: 10}
>>> mode = max((v, k) for k, v in frequencies.iteritems())[1]
>>> mode
1
>>> max_freq = max(frequencies.itervalues())
>>> modes = [k for k, v in frequencies.iteritems() if v == max_freq]
>>> modes
[1]
我更喜欢使用decorate-sort-undecorate惯用法来cmp
关键字。我认为它更具可读性。可能那只是我。
答案 2 :(得分:2)
请注意,从Python 3.8
开始,标准库包含statistics.multimode
函数,以最先出现的顺序返回最频繁出现的值的列表:
from statistics import multimode
multimode([1, 1, 2, 3, 4, 4])
# [1, 4]
答案 3 :(得分:1)
你可以在迭代时使用计数器作为最高值,如下所示:
def mode(valueList):
frequencies = {}
mx = None
for value in valueList:
if value in frequencies:
frequencies[value] += 1
else:
frequencies[value] = 1
if not mx or frequencies[value] > mx[1]:
mx = (value, frequencies[value])
mode = mx[0]
return mode
使用nlargest的多种模式的另一种方法,它可以为您提供字典的N个最大值:
from heapq import nlargest
import operator
def mode(valueList, nmodes):
frequencies = {}
for value in valueList:
frequencies[value] = frequencies.get(value, 0) + 1
return [x[0] for x in nlargest(nmodes,frequencies.iteritems(),operator.itemgetter(1))]