我正在尝试计算Python中值列表的模式(最常见的值).我提出了一个解决方案,无论如何都给出了错误的答案,但后来我才意识到我的数据可能是短期的;
ie 1,1,2,3,4,4 mode = 1 & 4
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止提出的:
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
Run Code Online (Sandbox Code Playgroud)
我认为这里的问题是我输出的值而不是最大值的指针.无论如何,任何人都可以建议一个更好的方法,这可以在有多个模式的情况下工作吗?或者说我怎么能解决到目前为止我所得到的并确定单一模式?
你可能会说我对python很新,谢谢你的帮助.
编辑:应该提到我在Python 2.4中
在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))
Run Code Online (Sandbox Code Playgroud)
注意使用匿名函数(lambda)来检查一对是否(_, f)与最频繁的元素具有相同的频率.
嗯,第一个问题是,是的,你是在返回值frequences而不是键.这意味着你获得模式的计数,而不是模式本身.通常,要获取模式,您可以使用key关键字参数max,如下所示:
>>> max(frequencies, key=counts.get())
Run Code Online (Sandbox Code Playgroud)
但在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]
Run Code Online (Sandbox Code Playgroud)
我更喜欢将decorate-sort-undecorate成语用于cmp关键字.我认为它更具可读性.可能那只是我.
请注意,从 开始Python 3.8,标准库包含statistics.multimode按首次遇到的顺序返回最常出现的值的列表的函数:
from statistics import multimode
multimode([1, 1, 2, 3, 4, 4])
# [1, 4]
Run Code Online (Sandbox Code Playgroud)