python - rstrip - 파이썬 title 함수




목록 항목의 발생을 계산하는 방법은 무엇입니까? (15)

어떤 아이템이 주어지면, 어떻게 파이썬의리스트에서 그것의 어커런스를 셀 수 있습니까?

다음은 예제 목록입니다.

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

그리고 컬렉션이 있습니다. 카운터. 모든 반복 가능 항목을 목록이 아닌 카운터로 덤프 할 수 있으며 카운터는 요소 수의 데이터 구조를 보유합니다.

용법:

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

카운터는 파이썬 사전을 기반으로하며 키는 요소이므로 키를 해시 할 수 있어야합니다. 기본적으로 중복 요소를 허용하는 세트와 같습니다.

collections.Counter 추가 사용. collections.Counter

카운터에서 iterables를 더하거나 뺄 수 있습니다.

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

팬더 왜?

또 다른 대답은 다음과 같습니다.

왜 팬더를 사용하지 않습니까?

팬더는 일반적인 라이브러리이지만 표준 라이브러리에는 없습니다. 요구 사항을 추가하는 것은 중요하지 않습니다.

표준 라이브러리뿐만 아니라 목록 객체 자체에도이 유스 케이스에 대한 솔루션이 내장되어 있습니다.

프로젝트에 팬더가 필요하지 않은 경우이 기능을 사용하기 위해 팬더를 요구하는 것은 어리석은 일입니다.

어떤 아이템이 주어지면, 어떻게 파이썬의리스트에서 그것의 어커런스를 셀 수 있습니까?


다음은 세 가지 솔루션입니다.

가장 빠른 방법은 for 루프를 사용하고 Dict에 저장하는 것입니다.

import time
from collections import Counter


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


z = [1,1,1,1,2,2,2,2,3,3,4,5,5,234,23,3,12,3,123,12,31,23,13,2,4,23,42,42,34,234,23,42,34,23,423,42,34,23,423,4,234,23,42,34,23,4,23,423,4,23,4]


#Solution 1 - Faster
st = time.monotonic()
for i in range(1000000):
    b = countElement(z)
et = time.monotonic()
print(b)
print('Simple for loop and storing it in dict - Duration: {}'.format(et - st))

#Solution 2 - Fast
st = time.monotonic()
for i in range(1000000):
    a = Counter(z)
et = time.monotonic()
print (a)
print('Using collections.Counter - Duration: {}'.format(et - st))

#Solution 3 - Slow
st = time.monotonic()
for i in range(1000000):
    g = dict([(i, z.count(i)) for i in set(z)])
et = time.monotonic()
print(g)
print('Using list comprehension - Duration: {}'.format(et - st))

결과

#Solution 1 - Faster
{1: 4, 2: 5, 3: 4, 4: 6, 5: 2, 234: 3, 23: 10, 12: 2, 123: 1, 31: 1, 13: 1, 42: 5, 34: 4, 423: 3}
Simple for loop and storing it in dict - Duration: 12.032000000000153
#Solution 2 - Fast
Counter({23: 10, 4: 6, 2: 5, 42: 5, 1: 4, 3: 4, 34: 4, 234: 3, 423: 3, 5: 2, 12: 2, 123: 1, 31: 1, 13: 1})
Using collections.Counter - Duration: 15.889999999999418
#Solution 3 - Slow
{1: 4, 2: 5, 3: 4, 4: 6, 5: 2, 34: 4, 423: 3, 234: 3, 42: 5, 12: 2, 13: 1, 23: 10, 123: 1, 31: 1}
Using list comprehension - Duration: 33.0

Python 2.7 또는 3을 사용하고 있고 각 요소에 대해 발생 횟수를 원하면 다음을 수행하십시오.

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

numpy의 bincount 를 사용하는 것이 좋지만, 음수가 아닌 정수가있는 1 차원 배열에서만 작동합니다. 또한 결과 배열은 혼동을 줄 수 있습니다 (원래 목록의 최소에서 최대까지의 정수가 포함되어 있으며 누락 된 정수를 0으로 설정 함).

numpy를 사용하는 더 좋은 방법은 return_counts 속성이 True로 설정된 unique 함수를 사용하는 것입니다. 고유 한 값의 배열과 각 고유 값의 어커런스가있는 튜플을 반환합니다.

# a = [1, 1, 0, 2, 1, 0, 3, 3]
a_uniq, counts = np.unique(a, return_counts=True)  # array([0, 1, 2, 3]), array([2, 3, 1, 2]

우리는 그들을 다음과 같이 쌍을 이룰 수 있습니다.

dict(zip(a_uniq, counts))  # {0: 2, 1: 3, 2: 1, 3: 2}

또한 다른 데이터 유형 및 "2d 목록"과도 작동합니다.

>>> a = [['a', 'b', 'b', 'b'], ['a', 'c', 'c', 'a']]
>>> dict(zip(*np.unique(a, return_counts=True)))
{'a': 3, 'b': 3, 'c': 2}

나는 오늘이 문제를 가지고 있었고, 내가 그렇게 확인하기 전에 내 자신의 해결책을 굴렸다. 이:

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

실제로 Python 2.7의 경우 카운터 솔루션보다 약간 빠릅니다.


내장 모듈 operatorcountOf 메소드를 사용할 수도 있습니다.

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

일반적인 유형의 다양한 요소의 수를 계산하려면 다음을 수행하십시오.

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 개


특정 요소에 대해 여러 번 발생 시키려면 다음을 수행하십시오.

>>> from collections import Counter
>>> z = ['blue', 'red', 'blue', 'yellow', 'blue', 'red']
>>> single_occurrences = Counter(z)
>>> print(single_occurrences.get("blue"))
3
>>> print(single_occurrences.values())
dict_values([3, 2, 1])

필자는 제안 된 모든 솔루션 (및 몇 가지 새로운 솔루션)과 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,
    )


목록에서 한 항목의 출현 계산

하나의 목록 항목 만 계산하려면 count() 사용할 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 가 목록을 집계하는 데 얼마나 더 빨랐는지 확인했다. 나는 두 개의 값을 가지고 두 가지 방법을 시도해 보았고 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]

한 번에 모든 값계산 하려면 다음과 같이 numpy 배열과 bincount 를 사용하여 매우 빠르게 수행 할 수 있습니다.

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

주는

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

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

def countfrequncyinarray(arr1):
    r=len(arr1)
    return {i:arr1.count(i) for i in range(1,r+1)}
arr1=[4,4,4,4]
a=countfrequncyinarray(arr1)
print(a)

sum([1 for elem in <yourlist> if elem==<your_value>])

your_value의 발생 수를 반환합니다.





count