2

能够使用双峰列表等。

到目前为止我的尝试:

testlist = [1,2,3,3,2,1,4,2,2,3,4,3,3,4,5,3,2,4,55,6,7,4,3,45,543,4,53,4,53,234]

.

from collections import Counter

def modal_1(xs):
    cntr = Counter(xs).most_common()
    val,count = cntr[0]
    return (v for v,c in cntr if c is count)

print(list(modal_1(testlist)))
>>> [3, 4]

——或者类似的东西——

def modal_2(xs):
       cntr = Counter(xs).most_common()
       val,count = cntr[0]
       return takewhile(lambda x: x[1] is count, cntr)

print(list(modal_2(testlist)))
>>> [(3, 7), (4, 7)]

请不要回答 - 使用 numpy 等。

笔记 :

Counter(xs).most_common(1)

返回 n 个模态值的第一个“模态”。如果有两个。它只会返回第一个。真可惜……因为这会使这一切变得容易得多。


好的,所以我很惊讶我原来的一个选项实际上是一个很好的方法。对于现在想要在列表中查找 n 模态数字的任何人,我会建议以下选项。这两个函数都适用于超过 1000 个值的列表

所有这些 (number,count) 的返回列表,其中所有元组的 count 都是相同的。我认为最好有这个,然后将其解析为您心中的愿望。

使用takewhile:

from collections import Counter
from itertools import takewhile

def modal_3(xs):
    counter = Counter(xs).most_common()
    mx = counter[0][1]
    return takewhile(lambda x: x[1] == mx, counter)

print(list(modal_3(testlist)))
>>> [(3, 7), (4, 7)]

使用 groupby:

from collections import Counter
from itertools import groupby
from operator import itemgetter

def modal_4(xs):    
    container = Counter(xs)
    return next(groupby(container.most_common(), key=itemgetter(1)))[1]

print(list(modal_4(testlist)))
>>> [(3, 7), (4, 7)]

以及最终的、pythonic 和最快的方式:

def modal_5(xs):

    def _mode(xs):
        for x in xs:
            if x[1] != xs[0][1]:
                break
            yield x

    counter = collections.Counter(xs).most_common()

    return [ x for x in _mode(counter) ]

感谢大家的帮助和信息。

4

3 回答 3

3

我认为你的第二个例子是最好的,有一些小的修改:

from itertools import takewhile
from collections import Counter

def modal(xs):
       counter = Counter(xs).most_common()
       _, count = counter[0]
       return takewhile(lambda x: x[1] == count, counter)

这里的改变是使用==而不是is-is检查身份,虽然对于某些值来说是真的,因为 Pythonint在后台用 s 做了一些魔法来缓存它们,但不会一直都是真的,也不应该依赖在这种情况下。

>>> a = 1
>>> a is 1
True
>>> a = 300
>>> a is 300
False
于 2012-06-21T21:34:33.740 回答
2
>>> testlist = [1,2,3,3,2,1,4,2,2,3,4,3,3,4,5,3,2,4,55,6,7,4,3,45,543,4,53,4,53,234]
>>> dic={x:testlist.count(x) for x in set(testlist)}

>>> [x for x in dic if dic[x]==max(dic.values())]

[3, 4]
于 2012-06-21T21:36:36.857 回答
2

什么?takewhile但是没有groupby

>>> from collections import Counter
>>> testlist = [1,2,3,3,2,1,4,2,2,3,4,3,3,4,5,3,2,4,55,6,7,4,3,45,543,4,53,4,53,234]
>>> cntr = Counter(testlist)
>>> from itertools import groupby
>>> list(x[0] for x in next(groupby(cntr.most_common(), key=lambda x:x[1]))[1])
[3, 4]
于 2012-06-21T22:59:20.467 回答