Câu hỏi Cách đếm số lần xuất hiện của một mục danh sách?


Cho một mục, làm thế nào tôi có thể đếm sự xuất hiện của nó trong một danh sách bằng Python?


1087
2018-04-08 13:30


gốc




Các câu trả lời:


Nếu bạn chỉ muốn đếm một mục, hãy sử dụng count phương pháp:

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

Đừng sử dụng điều này nếu bạn muốn đếm nhiều mục. Đang gọi count trong vòng lặp yêu cầu một đường chuyền riêng biệt trên danh sách cho mọi count cuộc gọi, có thể là thảm họa cho hiệu suất. Nếu bạn muốn đếm tất cả các mục, hoặc thậm chí chỉ là nhiều mục, hãy sử dụng Counter, như được giải thích trong các câu trả lời khác.


1431
2018-04-08 13:31



mylist = [1,7,7,7,3,9,9,9,7,9,10,0] print sorted(set([i for i in mylist if mylist.count(i)>2])) - cpp-coder


Nếu bạn đang sử dụng Python 2.7 hoặc 3 và bạn muốn số lần xuất hiện cho mỗi phần tử:

>>> from collections import Counter
>>> z = ['blue', 'red', 'blue', 'yellow', 'blue', 'red']
>>> Counter(z)
Counter({'blue': 3, 'red': 2, 'yellow': 1})

1363
2018-04-29 07:44



Tôi đã thấy rằng khi sử dụng rất nhiều (nói về hàng triệu chuỗi) rằng nó rất chậm vì các cuộc gọi đến isinstance. Vì vậy, nếu bạn chắc chắn về dữ liệu mà bạn đang làm việc với, nó có thể là tốt hơn để viết một chức năng tùy chỉnh mà không cần loại và kiểm tra cá thể. - Bram Vanroy


Đếm số lần xuất hiện của một mục trong danh sách

Để đếm số lần xuất hiện của một mục danh sách bạn có thể sử dụng count()

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

Đếm số lần xuất hiện của tất cả các các mục trong danh sách còn được gọi là "kiểm đếm" danh sách hoặc tạo bộ đếm kiểm đếm.

Đếm tất cả các mục có số đếm ()

Để đếm số lần xuất hiện của các mục trong l người ta chỉ đơn giản có thể sử dụng một danh sách hiểu và count() phương pháp

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

(hoặc tương tự với từ điển dict((x,l.count(x)) for x in set(l)))

Thí dụ:

>>> 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}

Đếm tất cả các mục có Counter ()

Ngoài ra, có nhanh hơn Counter lớp học từ collections thư viện

Counter(l)

Thí dụ:

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

Truy cập nhanh hơn bao nhiêu?

Tôi đã kiểm tra nhanh hơn bao nhiêu Counter là dành cho danh sách kiểm đếm. Tôi đã thử cả hai phương pháp với một vài giá trị n và nó xuất hiện Counter là nhanh hơn bởi một yếu tố không đổi khoảng 2.

Đây là kịch bản tôi đã sử dụng:

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)

Và đầu ra:

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

186
2018-05-28 10:58



Counter Là đường nhanh hơn cho các danh sách lớn hơn. Phương thức đọc danh sách là O (n ^ 2), Counter phải là O (n). - fhucho
Bộ đếm không nhanh hơn với hệ số 2, Bộ đếm nhanh hơn hệ số của n (O (n ^ 2) so với O (n)). - Martijn Pieters♦
count() cũng hoạt động trên dây, chỉ cần nói - Jacob Schneider
Tôi đã thấy rằng khi sử dụng rất nhiều (nói về hàng triệu chuỗi) rằng nó rất chậm vì các cuộc gọi đến isinstance. Vì vậy, nếu bạn chắc chắn về dữ liệu mà bạn đang làm việc với, nó có thể là tốt hơn để viết một chức năng tùy chỉnh mà không cần loại và kiểm tra cá thể. - Bram Vanroy


Một cách khác để có được số lần xuất hiện của từng mục, trong một từ điển:

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

56
2017-10-20 22:38



này trông giống như một trong những cấu trúc mà tôi thường nghĩ ra trong cái nóng của trận chiến, nhưng nó sẽ chạy qua một lần len (a) có nghĩa là phức tạp thời gian chạy bậc hai (vì mỗi lần chạy phụ thuộc vào len (a) một lần nữa). - Nicolas78
sẽ dict ((i, a.count (i)) cho i trong bộ (a)) được chính xác hơn và nhanh hơn? - hugo24
@ hugo24: Một chút, nhưng nó sẽ không nhanh hơn trong trường hợp xấu nhất; nó sẽ mất n * (number of different items) hoạt động, không tính thời gian cần thiết để tạo bộ. Sử dụng collections.Counter thực sự tốt hơn nhiều. - Clément


list.count(x) trả về số lần x xuất hiện trong danh sách

xem: http://docs.python.org/tutorial/datastructures.html#more-on-lists


40
2018-04-08 13:34





Nếu bạn muốn đếm tất cả các giá trị cùng một lúc bạn có thể làm điều đó rất nhanh bằng cách sử dụng các mảng numpy và bincount như sau

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

cung cấp cho

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

27
2017-11-19 10:53





Cho một mục, làm thế nào tôi có thể đếm sự xuất hiện của nó trong một danh sách bằng Python?

Dưới đây là danh sách ví dụ:

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

list.count

list.count phương pháp

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

Điều này làm việc tốt cho bất kỳ danh sách. Tuples cũng có phương thức này:

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

collections.Counter

Và sau đó là collections.Counter. Bạn có thể đổ bất kỳ iterable nào vào một Counter, không chỉ là một danh sách, và Counter sẽ giữ lại một cấu trúc dữ liệu về số lượng các phần tử.

Sử dụng:

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

Bộ đếm được dựa trên các từ điển Python, khóa của chúng là các phần tử, do đó, các khóa cần phải được băm. Về cơ bản chúng giống như các bộ cho phép các phần tử dư thừa vào chúng.

Sử dụng thêm collections.Counter

Bạn có thể cộng hoặc trừ với các lần lặp từ bộ đếm của mình:

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

Và bạn cũng có thể thực hiện các thao tác đa bộ với bộ đếm:

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

Tại sao không phải gấu trúc?

Một câu trả lời khác cho thấy:

Tại sao không sử dụng gấu trúc?

Pandas là một thư viện phổ biến, nhưng nó không nằm trong thư viện chuẩn. Thêm nó như là một phụ thuộc là không tầm thường.

Có các giải pháp dựng sẵn cho trường hợp sử dụng này trong chính đối tượng danh sách cũng như trong thư viện chuẩn.

Nếu dự án của bạn không yêu cầu gấu trúc, nó sẽ là ngu ngốc để làm cho nó một yêu cầu chỉ cho chức năng này.


23
2018-04-13 12:50





Tôi đã so sánh tất cả các giải pháp được đề xuất (và một vài giải pháp mới) với perfplot (một dự án nhỏ của tôi).

Đếm một mục

Đối với mảng đủ lớn, hóa ra là

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

hơi nhanh hơn các giải pháp khác.

enter image description here

Đếm tất cả các mặt hàng

Được thành lập trước,

numpy.bincount(a)

là những gì bạn muốn.

enter image description here


Mã để tái tạo các ô:

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

20
2017-09-13 10:32



numpy.bincount () sẽ chỉ hoạt động đối với các danh sách có các mục int. - Mukarram Pasha


Nếu bạn có thể sử dụng pandas, sau đó value_counts để giải cứu.

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

Nó cũng tự động sắp xếp kết quả dựa trên tần số.

Nếu bạn muốn kết quả nằm trong danh sách danh sách, hãy làm như sau

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

14
2018-01-17 07:56





Tại sao không sử dụng Pandas?

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

Đầu ra:

a    3
d    2
b    1
c    1
dtype: int64

Nếu bạn đang tìm kiếm một số phần tử cụ thể, hãy nói một, thử:

my_count['a']

Đầu ra:

3

13
2017-10-17 17:15