在Python中计算多模式列表中的模式

时间:2012-03-05 13:46:32

标签: python statistics

我正在尝试计算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中

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))]