python python统计列表中的重复项出现的次数 - 如何统计列表项的出现次数?




list重复项 numpy统计出现次数 (15)

给定一个项目,我如何计算它在Python中的列表中的出现次数?


Answers

from collections import Counter
country=['Uruguay', 'Mexico', 'Uruguay', 'France', 'Mexico']
count_country = Counter(country)
output_list= [] 

for i in count_country:
    output_list.append([i,count_country[i]])
print output_list

输出列表:

[['Mexico', 2], ['France', 1], ['Uruguay', 2]]


如果你可以使用pandas ,那么value_counts就是为了救援。

>>> import pandas as pd
>>> a = [1, 2, 3, 4, 1, 4, 1]
>>> pd.Series(a).value_counts()
1    3
4    2
3    1
2    1
dtype: int64

它也会根据频率自动分类结果。

如果您希望结果在列表中,请按照以下操作

>>> pd.Series(a).value_counts().reset_index().values.tolist()
[[1, 3], [4, 2], [3, 1], [2, 1]]

可能不是最高效的,需要额外的通行证才能删除重复项。

功能实现:

arr = np.array(['a','a','b','b','b','c'])
print(set(map(lambda x  : (x , list(arr).count(x)) , arr)))

返回:

{('c', 1), ('b', 3), ('a', 2)}

或者返回dict

print(dict(map(lambda x  : (x , list(arr).count(x)) , arr)))

返回:

{'b': 3, 'c': 1, 'a': 2}

计算列表中一个项目的出现次数

为了统计只有一个列表项的出现,你可以使用count()

>>> l = ["a","b","b"]
>>> l.count("a")
1
>>> l.count("b")
2

统计列表中所有项目的出现次数也称为“统计”列表或创建计数计数器。

用count()计算所有项目

要计算l中项目的出现次数,可以简单地使用列表理解和count()方法

[[x,l.count(x)] for x in set(l)]

(或者dict((x,l.count(x)) for x in set(l))的字典dict((x,l.count(x)) for x in set(l))类似dict((x,l.count(x)) for x in set(l))

例:

>>> l = ["a","b","b"]
>>> [[x,l.count(x)] for x in set(l)]
[['a', 1], ['b', 2]]
>>> dict((x,l.count(x)) for x in set(l))
{'a': 1, 'b': 2}

用Counter()计数所有项目

或者, collections库中有更快的Counter

Counter(l)

例:

>>> l = ["a","b","b"]
>>> from collections import Counter
>>> Counter(l)
Counter({'b': 2, 'a': 1})

Counter有多快?

我检查了Counter对统计列表的速度有多快。 我用n的几个值试了两种方法,看起来Counter的速度大约为2。

这是我使用的脚本:

from __future__ import print_function
import timeit

t1=timeit.Timer('Counter(l)', \
                'import random;import string;from collections import Counter;n=1000;l=[random.choice(string.ascii_letters) for x in range(n)]'
                )

t2=timeit.Timer('[[x,l.count(x)] for x in set(l)]',
                'import random;import string;n=1000;l=[random.choice(string.ascii_letters) for x in range(n)]'
                )

print("Counter(): ", t1.repeat(repeat=3,number=10000))
print("count():   ", t2.repeat(repeat=3,number=10000)

输出:

Counter():  [0.46062711701961234, 0.4022796869976446, 0.3974247490405105]
count():    [7.779430688009597, 7.962715800967999, 8.420845870045014]

要计算具有通用类型的不同元素的数量:

li = ['A0','c5','A8','A2','A5','c2','A3','A9']

print sum(1 for el in li if el[0]=='A' and el[1] in '01234')

3 ,而不是6


您也可以使用内置模块operator countOf方法。

>>> import operator
>>> operator.countOf([1, 2, 3, 4, 1, 4, 1], 1)
3

如果你想立刻计算所有的值,你可以使用numpy数组和bincount非常快bincount按照如下步骤进行

import numpy as np
a = np.array([1, 2, 3, 4, 1, 4, 1])
np.bincount(a)

这使

>>> array([0, 3, 1, 1, 2])

如果您只需要一个项目的计数,请使用count方法:

>>> [1, 2, 3, 4, 1, 4, 1].count(1)
3

如果要计算多个项目,请不要使用此项。 在循环中调用count需要在每次count调用时对列表进行单独传递,这对性能可能是灾难性的。 如果您想要计算所有项目,或者甚至只计算多个项目,请使用Counter ,如其他答案中所述。


给定一个项目,我如何计算它在Python中的列表中的出现次数?

以下是一个示例列表:

>>> l = list('aaaaabbbbcccdde')
>>> l
['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'e']

list.count

list.count方法

>>> l.count('b')
4

这适用于任何列表。 元组也有这种方法:

>>> t = tuple('aabbbffffff')
>>> t
('a', 'a', 'b', 'b', 'b', 'f', 'f', 'f', 'f', 'f', 'f')
>>> t.count('f')
6

collections.Counter

然后有收藏品。计数器。 您可以将任何迭代器转储到Counter中,而不仅仅是一个列表,Counter将保留一个元素计数的数据结构。

用法:

>>> from collections import Counter
>>> c = Counter(l)
>>> c['b']
4

计数器基于Python字典,它们的键是元素,所以键需要可排除。 它们基本上就像允许冗余元素进入它们的集合。

进一步使用collections.Counter

你可以在计数器中添加或减去迭代次数:

>>> c.update(list('bbb'))
>>> c['b']
7
>>> c.subtract(list('bbb'))
>>> c['b']
4

你也可以用计数器进行多套操作:

>>> c2 = Counter(list('aabbxyz'))
>>> c - c2                   # set difference
Counter({'a': 3, 'c': 3, 'b': 2, 'd': 2, 'e': 1})
>>> c + c2                   # addition of all elements
Counter({'a': 7, 'b': 6, 'c': 3, 'd': 2, 'e': 1, 'y': 1, 'x': 1, 'z': 1})
>>> c | c2                   # set union
Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1, 'y': 1, 'x': 1, 'z': 1})
>>> c & c2                   # set intersection
Counter({'a': 2, 'b': 2})

为什么不是熊猫?

另一个答案表明:

为什么不使用熊猫?

熊猫是一个普通的图书馆,但它不在标准图​​书馆。 将它作为依赖项添加并不重要。

在列表对象本身以及标准库中都有这种用例的内置解决方案。

如果你的项目不需要熊猫,将它作为这个功能的一个要求是愚蠢的。


我将所有建议的解决方案(以及一些新的解决方案)与perfplot (我的一个小项目)进行了比较。

计数一个项目

对于足够大的阵列,事实证明

numpy.sum(numpy.array(a) == 1) 

比其他解决方案稍快。

计数所有项目

如前所述 ,

numpy.bincount(a)

是你想要的。

代码重现的情节:

from collections import Counter
from collections import defaultdict
import numpy
import operator
import pandas
import perfplot


def counter(a):
    return Counter(a)


def count(a):
    return dict((i, a.count(i)) for i in set(a))


def bincount(a):
    return numpy.bincount(a)


def pandas_value_counts(a):
    return pandas.Series(a).value_counts()


def occur_dict(a):
    d = {}
    for i in a:
        if i in d:
            d[i] = d[i]+1
        else:
            d[i] = 1
    return d


def count_unsorted_list_items(items):
    counts = defaultdict(int)
    for item in items:
        counts[item] += 1
    return dict(counts)


def operator_countof(a):
    return dict((i, operator.countOf(a, i)) for i in set(a))


perfplot.show(
    setup=lambda n: list(numpy.random.randint(0, 100, n)),
    n_range=[2**k for k in range(20)],
    kernels=[
        counter, count, bincount, pandas_value_counts, occur_dict,
        count_unsorted_list_items, operator_countof
        ],
    equality_check=None,
    logx=True,
    logy=True,
    )

2。

from collections import Counter
from collections import defaultdict
import numpy
import operator
import pandas
import perfplot


def counter(a):
    return Counter(a)


def count(a):
    return dict((i, a.count(i)) for i in set(a))


def bincount(a):
    return numpy.bincount(a)


def pandas_value_counts(a):
    return pandas.Series(a).value_counts()


def occur_dict(a):
    d = {}
    for i in a:
        if i in d:
            d[i] = d[i]+1
        else:
            d[i] = 1
    return d


def count_unsorted_list_items(items):
    counts = defaultdict(int)
    for item in items:
        counts[item] += 1
    return dict(counts)


def operator_countof(a):
    return dict((i, operator.countOf(a, i)) for i in set(a))


perfplot.show(
    setup=lambda n: list(numpy.random.randint(0, 100, n)),
    n_range=[2**k for k in range(20)],
    kernels=[
        counter, count, bincount, pandas_value_counts, occur_dict,
        count_unsorted_list_items, operator_countof
        ],
    equality_check=None,
    logx=True,
    logy=True,
    )

为什么不使用熊猫?

import pandas as pd

l = ['a', 'b', 'c', 'd', 'a', 'd', 'a']

# converting the list to a Series and counting the values
my_count = pd.Series(l).value_counts()
my_count

输出:

a    3
d    2
b    1
c    1
dtype: int64

如果你正在寻找一个特定的元素的数量,说一个 ,请尝试:

my_count['a']

输出:

3

我今天遇到了这个问题,并在我想检查SO之前推出了自己的解决方案。 这个:

dict((i,a.count(i)) for i in a)

大列表真的很慢。 我的解决方案

def occurDict(items):
    d = {}
    for i in items:
        if i in d:
            d[i] = d[i]+1
        else:
            d[i] = 1
return d

实际上比Counter解决方案快一点,至少对于Python 2.7来说。


# Python >= 2.6 (defaultdict) && < 2.7 (Counter, OrderedDict)
from collections import defaultdict
def count_unsorted_list_items(items):
    """
    :param items: iterable of hashable items to count
    :type items: iterable

    :returns: dict of counts like Py2.7 Counter
    :rtype: dict
    """
    counts = defaultdict(int)
    for item in items:
        counts[item] += 1
    return dict(counts)


# Python >= 2.2 (generators)
def count_sorted_list_items(items):
    """
    :param items: sorted iterable of items to count
    :type items: sorted iterable

    :returns: generator of (item, count) tuples
    :rtype: generator
    """
    if not items:
        return
    elif len(items) == 1:
        yield (items[0], 1)
        return
    prev_item = items[0]
    count = 1
    for item in items[1:]:
        if prev_item == item:
            count += 1
        else:
            yield (prev_item, count)
            count = 1
            prev_item = item
    yield (item, count)
    return


import unittest
class TestListCounters(unittest.TestCase):
    def test_count_unsorted_list_items(self):
        D = (
            ([], []),
            ([2], [(2,1)]),
            ([2,2], [(2,2)]),
            ([2,2,2,2,3,3,5,5], [(2,4), (3,2), (5,2)]),
            )
        for inp, exp_outp in D:
            counts = count_unsorted_list_items(inp) 
            print inp, exp_outp, counts
            self.assertEqual(counts, dict( exp_outp ))

        inp, exp_outp = UNSORTED_WIN = ([2,2,4,2], [(2,3), (4,1)])
        self.assertEqual(dict( exp_outp ), count_unsorted_list_items(inp) )


    def test_count_sorted_list_items(self):
        D = (
            ([], []),
            ([2], [(2,1)]),
            ([2,2], [(2,2)]),
            ([2,2,2,2,3,3,5,5], [(2,4), (3,2), (5,2)]),
            )
        for inp, exp_outp in D:
            counts = list( count_sorted_list_items(inp) )
            print inp, exp_outp, counts
            self.assertEqual(counts, exp_outp)

        inp, exp_outp = UNSORTED_FAIL = ([2,2,4,2], [(2,3), (4,1)])
        self.assertEqual(exp_outp, list( count_sorted_list_items(inp) ))
        # ... [(2,2), (4,1), (2,1)]

from functools import reduce #python 3

>>> l = [[1,2,3],[4,5,6], [7], [8,9]]
>>> reduce(lambda x,y: x+y,l)
[1, 2, 3, 4, 5, 6, 7, 8, 9]

示例中的extend()方法修改x而不是返回有用的值( reduce()期望值)。

reduce版本的更快方法是

>>> import operator
>>> l = [[1,2,3],[4,5,6], [7], [8,9]]
>>> reduce(operator.concat, l)
[1, 2, 3, 4, 5, 6, 7, 8, 9]






python list count