回答:
Counter
Python 2.7または3.xを使用していて、各要素の出現回数を知りたい場合に使用します。
>>> from collections import Counter
>>> z = ['blue', 'red', 'blue', 'yellow', 'blue', 'red']
>>> Counter(z)
Counter({'blue': 3, 'red': 2, 'yellow': 1})
isinstance
。したがって、操作しているデータについて確信がある場合は、型とインスタンスのチェックを行わずにカスタム関数を記述する方がよいでしょう。
isinstance
呼びますか?何百万もの文字列がある場合でも、呼び出しにCounter
は1つのisinstance
呼び出しのみが含まれ、その引数がマッピングであるかどうかを確認します。あなたはおそらく、あなたがいつも食べているものを誤って判断したのでしょう。
Counter
は、多数の反復可能オブジェクトを数えるのではなく、大きな反復可能オブジェクトを数えるようになりました。100万文字列の反復可能オブジェクトを数えるCounter
と、手動で実装するよりも速くなります。update
多くのイテラブルで呼び出したい場合は、でイテラブルを1つに結合することで、速度を上げることができる場合がありますitertools.chain
。
リスト内の1つのアイテムの出現回数を数える
使用できるリストアイテムを1つだけカウントする場合 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))
)
例:
>>> 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()ですべてのアイテムを数える
または、ライブラリのより高速なCounter
クラスがありcollections
ます
Counter(l)
例:
>>> l = ["a","b","b"]
>>> from collections import Counter
>>> Counter(l)
Counter({'b': 2, 'a': 1})
カウンターはどれくらい速いですか?
Counter
リストの集計がどれほど速いかを確認しました。私は両方の方法をいくつかの値で試してみましたが、約2の定数倍だけ高速であるn
ように見えますCounter
。
これが私が使用したスクリプトです:
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]
Counter
ある方法より速く、より大きなリストのため。リスト内包表記法はO(n ^ 2)でCounter
あり、O(n)でなければなりません。
isinstance
。したがって、操作しているデータについて確信がある場合は、型とインスタンスのチェックを行わずにカスタム関数を記述する方がよいでしょう。
辞書で、各項目の発生数を取得する別の方法:
dict((i, a.count(i)) for i in a)
n * (number of different items)
、それはセットを構築するのにかかる時間をカウントしない、動作を制御します。使用collections.Counter
は本当にはるかに優れています。
i
、辞書に同じ値の複数のキーを入力しようとするため、次のコードはエラーをスローしません。 dict((i, a.count(i)) for i in a)
list.count(x)
x
リストに現れる回数を返します
参照:http : //docs.python.org/tutorial/datastructures.html#more-on-lists
アイテムが与えられた場合、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
そして、collections.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,
)
あなたが使用できる場合は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]]
今日私はこの問題を抱えていて、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
少なくともPython 2.7では、実際にはCounterソリューションより少し高速です。
# 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)]
最速は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
itertools.groupby()
リスト内のすべての要素の数を取得するための別の可能性は、 itertools.groupby()
。
「重複」カウントあり
from itertools import groupby
L = ['a', 'a', 'a', 't', 'q', 'a', 'd', 'a', 'd', 'c'] # Input list
counts = [(i, len(list(c))) for i,c in groupby(L)] # Create value-count pairs as list of tuples
print(counts)
戻り値
[('a', 3), ('t', 1), ('q', 1), ('a', 1), ('d', 1), ('a', 1), ('d', 1), ('c', 1)]
最初の3つa
のを最初のグループとして組み合わせた方法に注目a
してください。他のグループはリストの下にあります。これは、入力リストL
がソートされなかったために発生します。これは、グループを実際に分離する必要がある場合に利点になることがあります。
ユニークなカウント
一意のグループ数が必要な場合は、入力リストを並べ替えるだけです。
counts = [(i, len(list(c))) for i,c in groupby(sorted(L))]
print(counts)
戻り値
[('a', 5), ('c', 1), ('d', 2), ('q', 1), ('t', 1)]
注:一意のカウントを作成するために、他の多くの回答は、groupby
ソリューションと比較してより簡単で読みやすいコードを提供します。ただし、ここでは、重複カウントの例に対応するものを示しています。
numpyのbincountを使用することが推奨されていましたが、負でない整数を持つ1 次元配列に対してのみ機能します。また、結果の配列は混乱する可能性があります(元のリストのminからmaxまでの整数の出現が含まれ、欠落している整数を0に設定します)。
numpyでそれを行うより良い方法は、属性をTrueに設定して一意の関数を使用することreturn_counts
です。一意の値の配列と各一意の値の発生の配列を含むタプルを返します。
# 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}
とても古い質問ですが、ライナーが見つからなかったので作りました。
# original numbers in list
l = [1, 2, 2, 3, 3, 3, 4]
# empty dictionary to hold pair of number and its count
d = {}
# loop through all elements and store count
[ d.update( {i:d.get(i, 0)+1} ) for i in l ]
print(d)
countOf
組み込みモジュールのメソッドを使用することもできますoperator
。
>>> import operator
>>> operator.countOf([1, 2, 3, 4, 1, 4, 1], 1)
3
countOf
実装されていますか?それはより明白なlist.count
(C実装から利益を得る)とどのように比較しますか?何か利点はありますか?
sum([1 for elem in <yourlist> if elem==<your_value>])
これにより、your_valueの出現回数が返されます
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)
l2=[1,"feto",["feto",1,["feto"]],['feto',[1,2,3,['feto']]]]
count=0
def Test(l):
global count
if len(l)==0:
return count
count=l.count("feto")
for i in l:
if type(i) is list:
count+=Test(i)
return count
print(Test(l2))
これは、リストのリスト内であっても、リスト内のアイテムを再帰的にカウントまたは検索します
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]))