python - एक सूची आइटम की घटनाओं की गणना कैसे करें?




9 Answers

यदि आप केवल एक आइटम की गिनती चाहते हैं, तो count विधि का उपयोग करें:

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

यदि आप एकाधिक आइटम गिनना चाहते हैं तो इसका उपयोग करें। लूप में कॉलिंग count लिए प्रत्येक count कॉल के लिए सूची में एक अलग पास की आवश्यकता होती है, जो प्रदर्शन के लिए विनाशकारी हो सकती है। यदि आप अन्य वस्तुओं की गणना करना चाहते हैं, या यहां तक ​​कि केवल कई आइटम, Counter उपयोग करें, जैसा कि अन्य उत्तरों में बताया गया है।

किसी आइटम को देखते हुए, मैं पाइथन में एक सूची में अपनी घटनाओं को कैसे गिन सकता हूं?




सूची में एक आइटम की घटनाओं की गणना करना

केवल एक सूची आइटम की घटनाओं की गिनती के लिए आप count() उपयोग कर सकते हैं

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

सूची में सभी वस्तुओं की घटनाओं की गणना करना एक सूची "टैलींग" के रूप में भी जाना जाता है, या एक टैली काउंटर बनाते हैं।

गिनती के साथ सभी वस्तुओं की गणना ()

l में वस्तुओं की घटनाओं की गिनती करने के लिए बस एक सूची समझ और count() विधि का उपयोग कर सकते हैं

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

काउंटर के साथ सभी वस्तुओं की गणना ()

वैकल्पिक रूप से, collections पुस्तकालय से तेज़ Counter क्लास है

Counter(l)

उदाहरण:

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

काउंटर कितना तेज़ है?

मैंने जांच की है कि सूचीकरण सूची के लिए 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]






किसी आइटम को देखते हुए, मैं पाइथन में एक सूची में अपनी घटनाओं को कैसे गिन सकता हूं?

यहां एक उदाहरण सूची दी गई है:

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

आप अपने काउंटर से पुनरावृत्तियों के साथ जोड़ या घटा सकते हैं:

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



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



यदि आप 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]]



आप अंतर्निहित मॉड्यूल operator की countOf विधि का भी उपयोग कर सकते हैं।

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



सबसे कुशल नहीं हो सकता है, डुप्लिकेट को हटाने के लिए एक अतिरिक्त पास की आवश्यकता है।

कार्यात्मक कार्यान्वयन:

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}



Related