順序付けられていないリストの要素の頻度を数える方法は?


237

順不同リストの要素の頻度を見つける必要があります

a = [1,1,1,1,2,2,2,2,3,3,4,5,5]

出力->

b = [4,4,2,1,2]

また、私はから重複を削除したいです

a = [1,2,3,4,5]

それらは常にその例のように注文されますか?
Farinha、2010年

@ピーター。はい、投稿目的でリストを並べ替えました。リストは常にソートされますか?
S.Lott、2009年

2
いいえ、リストは常に並べ替えられるとは限りません。これは宿題ではありません。
Bruce

ネットワークの次数分布のグラフをプロットしようとしています。
Bruce

5
@ピーター:役立つ情報で質問を更新してください。質問にはコメントを追加しないでください。質問の所有者です。完全で明確になるように修正できます。
S.Lott、2010年

回答:


147

注:を使用する前にリストをソートする必要がありますgroupby

リストが順序付きリストの場合はgroupbyitertoolsパッケージから使用できます。

a = [1,1,1,1,2,2,2,2,3,3,4,5,5]
from itertools import groupby
[len(list(group)) for key, group in groupby(a)]

出力:

[4, 4, 2, 1, 2]

いいですねgroupby。しかし、効率とdictアプローチの
違い

32
python groupbyは、表示される値が変化すると、新しいグループを作成します。この場合、1,1,1,2,1,1,1]は[3,1,3]を返します。[6,1]を期待している場合は、groupbyを使用する前にデータをソートしてください。
エヴァン

4
@CristianCiupitu: sum(1 for _ in group)
Martijn Pieters

6
これは解決策ではありません。出力では、何がカウントされたかはわかりません。
buhtz

8
[(key, len(list(group))) for key, group in groupby(a)]または{key: len(list(group)) for key, group in groupby(a)}@buhtz
Eric Pauley

532

Python 2.7(またはそれ以降)では、以下を使用できますcollections.Counter

import collections
a = [1,1,1,1,2,2,2,2,3,3,4,5,5]
counter=collections.Counter(a)
print(counter)
# Counter({1: 4, 2: 4, 3: 2, 5: 2, 4: 1})
print(counter.values())
# [4, 4, 2, 1, 2]
print(counter.keys())
# [1, 2, 3, 4, 5]
print(counter.most_common(3))
# [(1, 4), (2, 4), (3, 2)]

Python 2.6以前を使用している場合は、こちらからダウンロードできます。


1
@unutbu:3つのリストa、b、cがあり、aとbは同じままですが、cが変更された場合はどうなりますか?aとcが同じであるcの値を数える方法は?
ThePredator 2014年

@Srivatsan:状況がわかりません。詳しく説明できる新しい質問を投稿してください。
unutbu 2014年

1
カウンターオブジェクトから辞書{1:4、2:4、3:2、5:2、4:1}を抽出する方法はありますか?
Pavan

7
@Pavan:はのcollections.Counterサブクラスですdict。通常の辞書と同じように使用できます。ただし、本当に辞書が必要な場合は、を使用して辞書に変換できますdict(counter)
unutbu 2015年

1
3.6でも機能するため、2.7より大きいものを想定
kpierce8

108

Python 2.7以降では、辞書理解機能が導入されています。リストから辞書を作成すると、数が増えるだけでなく、重複を取り除くことができます。

>>> a = [1,1,1,1,2,2,2,2,3,3,4,5,5]
>>> d = {x:a.count(x) for x in a}
>>> d
{1: 4, 2: 4, 3: 2, 4: 1, 5: 2}
>>> a, b = d.keys(), d.values()
>>> a
[1, 2, 3, 4, 5]
>>> b
[4, 4, 2, 1, 2]

これは、元の質問のような整数とは対照的に、文字列のリストで非常にうまく機能します。
Glen Selle

15
セットを使用するとより高速になります:{x:a.count(x) for x in set(a)}
stenci

45
これは非常に非効率的です。a.count()は、の各要素に対して完全なトラバースを実行しa、これをO(N ^ 2)quadradicアプローチにします。collections.Counter()あるはるかに効率的な、それは線形時間(O(N))でカウントされるため。数字で、その手段は、このアプローチは対、長さ1000のリストについては、100万個の手順を実行しますちょうど1000ステップでCounter()、唯一の10 ^ 6など、リスト内の百万項目、カウンタによって必要とされている10 ^ 12のステップ
Martijn Pieters

3
@stenci:確かに、しかし、a.count()完全に使用することの恐怖は、そこでセットを使用した場合の効率よりも小さくなります。
Martijn Pieters

2
@MartijnPieters使用回数を減らすもう1つの理由:)
stenci

48

出現回数を数えるには:

from collections import defaultdict

appearances = defaultdict(int)

for curr in a:
    appearances[curr] += 1

重複を削除するには:

a = set(a) 

1
collections.defaultdictの+1。また、python 3.xでは、collections.Counterを検索します。これは、collections.defaultdict(int)と同じです。
hughdbrown、2010年

2
@hughdbrownは実際にCounterは、だけでなく、floatまたはを含む複数の数値型を使用できます。Decimalint
クリスチャンCiupitu 16

28

Python 2.7以降では、collections.Counterを使用してアイテムをカウントできます

>>> a = [1,1,1,1,2,2,2,2,3,3,4,5,5]
>>>
>>> from collections import Counter
>>> c=Counter(a)
>>>
>>> c.values()
[4, 4, 2, 1, 2]
>>>
>>> c.keys()
[1, 2, 3, 4, 5]

1
カウンターはデフォルトの辞書よりもはるかに遅く、デフォルトの辞書は手動での辞書の使用よりもはるかに遅いです。
ジョナサンレイ

@JonathanRayではなく、stackoverflow.com / a / 27802189/1382487 。
wsaleem

25

要素の頻度を数えるのはおそらく辞書で行うのが最も良いでしょう:

b = {}
for item in a:
    b[item] = b.get(item, 0) + 1

重複を削除するには、セットを使用します。

a = list(set(a))

3
@phkahler:私のものはこれよりほんの少しだけ良いでしょう。これを小さな変更で改善できる場合、別の回答を投稿する価値はほとんどありません。SOのポイントは、最良の答えを得ることです。これを編集することもできますが、元の作者が自分で改善できるようにしたいと思います。
S.Lott、2010年

1
@ S.Lottインポートする必要がないため、コードははるかにクリーンdefaultdictです。
bstrauch24 2018

なぜb:を初期化しないのb = {k:0 for k in a}ですか?
DylanYoung

20

itertools.groupbyこれは、順序付けされていない入力でも機能する別の簡潔な代替方法です:

from itertools import groupby

items = [5, 1, 1, 2, 2, 1, 1, 2, 2, 3, 4, 3, 5]

results = {value: len(list(freq)) for value, freq in groupby(sorted(items))}

結果

{1: 4, 2: 4, 3: 2, 4: 1, 5: 2}

16

あなたはこれを行うことができます:

import numpy as np
a = [1,1,1,1,2,2,2,2,3,3,4,5,5]
np.unique(a, return_counts=True)

出力:

(array([1, 2, 3, 4, 5]), array([4, 4, 2, 1, 2], dtype=int64))

最初の配列は値で、2番目の配列はこれらの値を持つ要素の数です。

だからあなたが数字で配列だけを取得したいなら、あなたはこれを使うべきです:

np.unique(a, return_counts=True)[1]

8
from collections import Counter
a=["E","D","C","G","B","A","B","F","D","D","C","A","G","A","C","B","F","C","B"]

counter=Counter(a)

kk=[list(counter.keys()),list(counter.values())]

pd.DataFrame(np.array(kk).T, columns=['Letter','Count'])

このコードスニペットが解決策になる可能性がありますが、説明を含めると、投稿の品質を向上させるのに役立ちます。あなたが将来の読者のための質問に答えていることを覚えておいてください、そしてそれらの人々はあなたのコード提案の理由を知らないかもしれません
Rahul Gupta '28

はい、ラフル・グプタ
Anirban Lahiri、2017

7
seta = set(a)
b = [a.count(el) for el in seta]
a = list(seta) #Only if you really want it.

4
リストの使用はcount途方もなく高価であり、このシナリオでは必要ありません。
Idan K 2010

@IdanKなぜカウントが高価なのですか?
Kritika Rajain

@KritikaRajainリスト内の一意の要素ごとに、リスト全体を反復処理してカウント(リスト内の一意の要素の数の2次)を生成します。代わりに、リストを1回繰り返し、各一意の要素の数を数えることができます(リストのサイズに線形)。リストに一意の要素が1つしかない場合、結果は同じになります。さらに、このアプローチには追加の中間セットが必要です。
DylanYoung


4

最初の質問では、リストを反復処理し、辞書を使用して要素の存在を追跡します。

2番目の質問では、単にset演算子を使用します。


4
最初の答えについて詳しく説明してください
Bruce

3

この答えはより明確です

a = [1,1,1,1,2,2,2,2,3,3,3,4,4]

d = {}
for item in a:
    if item in d:
        d[item] = d.get(item)+1
    else:
        d[item] = 1

for k,v in d.items():
    print(str(k)+':'+str(v))

# output
#1:4
#2:4
#3:3
#4:2

#remove dups
d = set(a)
print(d)
#{1, 2, 3, 4}

3
def frequencyDistribution(data):
    return {i: data.count(i) for i in data}   

print frequencyDistribution([1,2,3,4])

...

 {1: 1, 2: 1, 3: 1, 4: 1}   # originalNumber: count

3

私はかなり遅れていますが、これもうまくいき、他の人を助けるでしょう:

a = [1,1,1,1,2,2,2,2,3,3,4,5,5]
freq_list = []
a_l = list(set(a))

for x in a_l:
    freq_list.append(a.count(x))


print 'Freq',freq_list
print 'number',a_l

これを作成します。

Freq  [4, 4, 2, 1, 2]
number[1, 2, 3, 4, 5]

2
a = [1,1,1,1,2,2,2,2,3,3,4,5,5]

# 1. Get counts and store in another list
output = []
for i in set(a):
    output.append(a.count(i))
print(output)

# 2. Remove duplicates using set constructor
a = list(set(a))
print(a)
  1. Setコレクションは重複を許可しません。リストをset()コンストラクターに渡すと、完全に一意のオブジェクトの反復可能オブジェクトが提供されます。count()関数は、リストにあるオブジェクトが渡されると、整数のカウントを返します。これにより、一意のオブジェクトがカウントされ、各カウント値は空のリスト出力に追加して保存されます
  2. list()コンストラクタは、set(a)をリストに変換するために使用され、同じ変数aによって参照されます

出力

D:\MLrec\venv\Scripts\python.exe D:/MLrec/listgroup.py
[4, 4, 2, 1, 2]
[1, 2, 3, 4, 5]

2

辞書を使用した簡単な解決策。

def frequency(l):
     d = {}
     for i in l:
        if i in d.keys():
           d[i] += 1
        else:
           d[i] = 1

     for k, v in d.iteritems():
        if v ==max (d.values()):
           return k,d.keys()

print(frequency([10,10,10,10,20,20,20,20,40,40,50,50,30]))

max(d.values())最後のループでは変更されません。ループでは計算せ、ループのに計算します。
DylanYoung

1
#!usr/bin/python
def frq(words):
    freq = {}
    for w in words:
            if w in freq:
                    freq[w] = freq.get(w)+1
            else:
                    freq[w] =1
    return freq

fp = open("poem","r")
list = fp.read()
fp.close()
input = list.split()
print input
d = frq(input)
print "frequency of input\n: "
print d
fp1 = open("output.txt","w+")
for k,v in d.items():
fp1.write(str(k)+':'+str(v)+"\n")
fp1.close()

1
num=[3,2,3,5,5,3,7,6,4,6,7,2]
print ('\nelements are:\t',num)
count_dict={}
for elements in num:
    count_dict[elements]=num.count(elements)
print ('\nfrequency:\t',count_dict)

2
コードのみの回答は投稿しないでください。特に質問にすでに有効な回答がある場合は、コードを明確にしてください。
エリックA

1
from collections import OrderedDict
a = [1,1,1,1,2,2,2,2,3,3,4,5,5]
def get_count(lists):
    dictionary = OrderedDict()
    for val in lists:
        dictionary.setdefault(val,[]).append(1)
    return [sum(val) for val in dictionary.values()]
print(get_count(a))
>>>[4, 4, 2, 1, 2]

重複を削除して順序を維持するには:

list(dict.fromkeys(get_count(a)))
>>>[4, 2, 1]

1

Counterを使用して周波数を生成しています。コードの1行のテキストファイルの単語からの辞書

def _fileIndex(fh):
''' create a dict using Counter of a
flat list of words (re.findall(re.compile(r"[a-zA-Z]+"), lines)) in (lines in file->for lines in fh)
'''
return Counter(
    [wrd.lower() for wrdList in
     [words for words in
      [re.findall(re.compile(r'[a-zA-Z]+'), lines) for lines in fh]]
     for wrd in wrdList])

1

これを行う別の方法ですが、より強力で強力なライブラリーNLTKを使用します。

import nltk

fdist = nltk.FreqDist(a)
fdist.values()
fdist.most_common()

0

コレクションを使用しない別のアルゴリズムを使用したさらに別のソリューション:

def countFreq(A):
   n=len(A)
   count=[0]*n                     # Create a new list initialized with '0'
   for i in range(n):
      count[A[i]]+= 1              # increase occurrence for value A[i]
   return [x for x in count if x]  # return non-zero count

0

Pythonで提供されている組み込み関数を使用できます。

l.count(l[i])


  d=[]
  for i in range(len(l)):
        if l[i] not in d:
             d.append(l[i])
             print(l.count(l[i])

上記のコードは、リストの重複を自動的に削除し、元のリストと重複のないリストの各要素の頻度も出力します。

一発二羽!XD


0

このアプローチは、ライブラリを使用せず、シンプルかつ簡潔にしたい場合に使用できます。

a = [1,1,1,1,2,2,2,2,3,3,4,5,5]
marked = []
b = [(a.count(i), marked.append(i))[0] for i in a if i not in marked]
print(b)

o / p

[4, 4, 2, 1, 2]

0

記録のために、機能的な答え:

>>> L = [1,1,1,1,2,2,2,2,3,3,4,5,5]
>>> import functools
>>> >>> functools.reduce(lambda acc, e: [v+(i==e) for i, v in enumerate(acc,1)] if e<=len(acc) else acc+[0 for _ in range(e-len(acc)-1)]+[1], L, [])
[4, 4, 2, 1, 2]

あなたもゼロを数えるならそれはよりきれいです:

>>> functools.reduce(lambda acc, e: [v+(i==e) for i, v in enumerate(acc)] if e<len(acc) else acc+[0 for _ in range(e-len(acc))]+[1], L, [])
[0, 4, 4, 2, 1, 2]

説明:

  • 空から始めます accリストます。
  • の次の要素eLのサイズよりも小さい場合、accこの要素を更新するだけです。v+(i==e)つまりv+1、のインデックスiacc現在の要素eである場合は、それ以外の場合は前の値vです。
  • の次の要素eLのサイズ以上の場合、新しいをホストaccするために拡張するacc必要があります1

要素をソートする必要はありません(itertools.groupby)。負の数があると、奇妙な結果になります。


0

セットを使用して、これを行う別の方法を見つけました。

#ar is the list of elements
#convert ar to set to get unique elements
sock_set = set(ar)

#create dictionary of frequency of socks
sock_dict = {}

for sock in sock_set:
    sock_dict[sock] = ar.count(sock)

0

リスト内の一意の要素を見つけるには

a = [1,1,1,1,2,2,2,2,3,3,4,5,5]
a = list(set(a))

辞書を使用してソートされた配列内の一意の要素の数を見つけるには

def CountFrequency(my_list): 
# Creating an empty dictionary  
freq = {} 
for item in my_list: 
    if (item in freq): 
        freq[item] += 1
    else: 
        freq[item] = 1

for key, value in freq.items(): 
    print ("% d : % d"%(key, value))

# Driver function 
if __name__ == "__main__":  
my_list =[1, 1, 1, 5, 5, 3, 1, 3, 3, 1, 4, 4, 4, 2, 2, 2, 2] 

CountFrequency(my_list)

リファレンス GeeksforGeeks


-1

もう1つの方法は、辞書とlist.countを使用することです。

dicio = dict()

a = [1,1,1,1,2,2,2,2,3,3,4,5,5]

b = list()

c = list()

for i in a:

   if i in dicio: continue 

   else:

      dicio[i] = a.count(i)

      b.append(a.count(i))

      c.append(i)

print (b)

print (c)

-1
a=[1,2,3,4,5,1,2,3]
b=[0,0,0,0,0,0,0]
for i in range(0,len(a)):
    b[a[i]]+=1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.