Wie zähle ich die Häufigkeit der Elemente in einer ungeordneten Liste?


237

Ich muss die Häufigkeit von Elementen in einer ungeordneten Liste finden

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

Ausgabe->

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

Außerdem möchte ich die Duplikate von a entfernen

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

Sind sie immer wie in diesem Beispiel bestellt?
Farinha

@Peter. Ja, Sie haben die Liste zum Zwecke der Veröffentlichung sortiert. Wird die Liste immer sortiert?
S.Lott

2
Nein, die Liste wird nicht immer sortiert. Dies sind keine Hausaufgaben.
Bruce

Ich versuche, den Graphen der Gradverteilung eines Netzwerks zu zeichnen.
Bruce

5
@ Peter: Bitte aktualisieren Sie Ihre Frage mit den nützlichen Informationen. Bitte fügen Sie Ihrer Frage keine Kommentare hinzu - Sie besitzen die Frage, Sie können sie vollständig und klar korrigieren.
S.Lott

Antworten:


147

Hinweis: Sie sollten die Liste vor der Verwendung sortieren groupby.

Sie können groupbyaus itertoolsPaket verwenden, wenn die Liste eine geordnete Liste ist.

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

Ausgabe:

[4, 4, 2, 1, 2]

schön, mit groupby. Ich wundere mich jedoch über seine Effizienz im Vergleich zum Diktatansatz
Eli Bendersky

32
Die Python-Gruppe erstellt neue Gruppen, wenn sich der angezeigte Wert ändert. In diesem Fall würde 1,1,1,2,1,1,1] [3,1,3] zurückgeben. Wenn Sie [6,1] erwartet haben, müssen Sie die Daten nur sortieren, bevor Sie groupby verwenden.
Evan

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

6
Dies ist keine Lösung. Die Ausgabe sagt nicht, was gezählt wurde.
Buhz

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

532

In Python 2.7 (oder neuer) können Sie Folgendes verwenden 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)]

Wenn Sie Python 2.6 oder älter verwenden, können Sie es hier herunterladen .


1
@unutbu: Was ist, wenn ich drei Listen habe, a, b, c, für die a und b gleich bleiben, aber c sich ändert? Wie zählt man den Wert von c, für den a und c gleich sind?
ThePredator

@ Srivatsan: Ich verstehe die Situation nicht. Bitte posten Sie eine neue Frage, in der Sie näher darauf eingehen können.
Unutbu

1
Gibt es eine Möglichkeit, das Wörterbuch {1: 4, 2: 4, 3: 2, 5: 2, 4: 1} aus dem Gegenobjekt zu extrahieren?
Pavan

7
@Pavan: collections.Counterist eine Unterklasse von dict. Sie können es genauso verwenden wie ein normales Diktat. Wenn Sie jedoch wirklich ein Diktat möchten, können Sie es mit in ein Diktat konvertieren dict(counter).
Unutbu

1
Funktioniert auch in 3.6, also nehmen Sie etwas größer als 2.7 an
kpierce8

108

Python 2.7+ führt das Wörterbuchverständnis ein. Wenn Sie das Wörterbuch aus der Liste erstellen, erhalten Sie die Anzahl und können Duplikate entfernen.

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

Dies funktioniert sehr gut mit Listen von Zeichenfolgen im Gegensatz zu Ganzzahlen wie der ursprünglichen Frage.
Glen Selle

15
Es ist schneller mit einem Satz:{x:a.count(x) for x in set(a)}
Stenci

45
Dies ist äußerst ineffizient . a.count()führt für jedes Element eine vollständige Durchquerung durch a, wodurch dies zu einem O (N ^ 2) -Quadrad-Ansatz wird. collections.Counter()ist viel effizienter, weil es in linearer Zeit (O (N)) zählt. In Zahlen bedeutet dies, dass dieser Ansatz 1 Million Schritte für eine Liste mit einer Länge von 1000 ausführt, gegenüber nur 1000 Schritten mit Counter()10 ^ 12 Schritten, wobei Counter nur 10 ^ 6 für eine Million Elemente in einer Liste usw. benötigt.
Martijn Pieters

3
@stenci: sicher, aber der Schrecken, a.count()völlig in den Schatten zu stellen, stellt die Effizienz in Frage, ein Set dort benutzt zu haben.
Martijn Pieters

2
@MartijnPieters ein Grund mehr, es weniger oft zu verwenden :)
stenci

48

So zählen Sie die Anzahl der Auftritte:

from collections import defaultdict

appearances = defaultdict(int)

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

So entfernen Sie Duplikate:

a = set(a) 

1
+1 für collection.defaultdict. Suchen Sie in Python 3.x auch nach Sammlungen. Es ist dasselbe wie collection.defaultdict (int).
Hughdbrown

2
@hughdbrown, Counterkann tatsächlich mehrere numerische Typen verwenden, einschließlich floatoder Decimalnicht nur int.
Cristian Ciupitu

28

In Python 2.7+ können Sie Sammlungen verwenden. Zähler zum Zählen von Elementen

>>> 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
Der Zähler ist viel langsamer als das Standarddiktat, und das Standarddiktat ist viel langsamer als die manuelle Verwendung eines Diktats.
Jonathan Ray

@ JonathanRay, nicht mehr, stackoverflow.com/a/27802189/1382487 .
Wsaleem

25

Das Zählen der Häufigkeit von Elementen erfolgt wahrscheinlich am besten mit einem Wörterbuch:

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

Verwenden Sie einen Satz, um die Duplikate zu entfernen:

a = list(set(a))

3
@phkahler: Meins wäre nur ein kleines bisschen besser als dieses. Es lohnt sich kaum, eine separate Antwort zu veröffentlichen, wenn dies mit einer kleinen Änderung verbessert werden kann. Der Sinn von SO ist es, die besten Antworten zu bekommen . Ich könnte dies einfach bearbeiten, aber ich ziehe es vor, dem ursprünglichen Autor die Möglichkeit zu geben, seine eigenen Verbesserungen vorzunehmen.
S.Lott

1
@ S.Lott Der Code ist viel sauberer, ohne importiert werden zu müssen defaultdict.
bstrauch24

Warum nicht b: vorinitialisieren b = {k:0 for k in a}?
DylanYoung

20

Hier ist eine weitere Alternative, itertools.groupbydie auch für ungeordnete Eingaben funktioniert:

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

Ergebnisse

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

16

Du kannst das:

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

Ausgabe:

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

Das erste Array ist Werte, und das zweite Array ist die Anzahl der Elemente mit diesen Werten.

Wenn Sie also nur ein Array mit den Zahlen erhalten möchten, sollten Sie Folgendes verwenden:

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

Während dieses Code-Snippet die Lösung sein kann, hilft das Hinzufügen einer Erklärung wirklich, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage für Leser in Zukunft beantworten und diese Personen möglicherweise die Gründe für Ihren Code-Vorschlag nicht kennen
Rahul Gupta

Ja, das wird Rahul Gupta
Anirban Lahiri

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

4
Die Verwendung von Listen countist in diesem Szenario lächerlich teuer und unangebracht.
Idan K

@IdanK warum zählen ist teuer?
Kritika Rajain

@KritikaRajain Für jedes eindeutige Element in der Liste durchlaufen Sie die gesamte Liste, um eine Anzahl zu generieren (quadratisch in der Anzahl der eindeutigen Elemente in der Liste). Stattdessen können Sie die Liste einmal durchlaufen und die Anzahl der einzelnen eindeutigen Elemente (linear in der Größe der Liste) hochzählen. Wenn Ihre Liste nur ein eindeutiges Element enthält, ist das Ergebnis dasselbe. Darüber hinaus erfordert dieser Ansatz einen zusätzlichen Zwischensatz.
DylanYoung


4

Wiederholen Sie bei Ihrer ersten Frage die Liste und verwenden Sie ein Wörterbuch, um das Vorhandensein von Elementen zu verfolgen.

Verwenden Sie für Ihre zweite Frage einfach den Set-Operator.


4
Können Sie bitte die erste Antwort näher erläutern
Bruce

3

Diese Antwort ist expliziter

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

Ich bin ziemlich spät dran, aber das wird auch funktionieren und anderen helfen:

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

wird dies produzieren ..

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. Die Set-Auflistung erlaubt keine Duplikate. Wenn Sie eine Liste an den set () -Konstruktor übergeben, erhalten Sie eine Iteration von völlig eindeutigen Objekten. Die Funktion count () gibt eine Ganzzahl zurück, wenn ein Objekt in einer Liste übergeben wird. Damit werden die eindeutigen Objekte gezählt und jeder Zählwert durch Anhängen an eine leere Listenausgabe gespeichert
  2. Der Konstruktor list () wird verwendet, um die Menge (a) in list umzuwandeln und von derselben Variablen a referenziert zu werden

Ausgabe

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

2

Einfache Lösung mit einem Wörterbuch.

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())wird sich in der letzten Schleife nicht ändern. Berechnen Sie es nicht in der Schleife, sondern vor der Schleife.
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
Bitte posten Sie keine Nur-Code-Antworten, sondern klären Sie Ihren Code, insbesondere wenn eine Frage bereits eine gültige Antwort hat.
Erik 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]

So entfernen Sie Duplikate und pflegen die Reihenfolge:

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

1

Ich benutze Counter, um eine Frequenz zu generieren. Diktieren Sie aus Textdatei-Wörtern in 1 Codezeile

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

Ein anderer Ansatz, wenn auch mit einer schwereren, aber leistungsstarken Bibliothek - NLTK.

import nltk

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

0

Noch eine Lösung mit einem anderen Algorithmus ohne Verwendung von Sammlungen:

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

Sie können die in Python integrierte Funktion verwenden

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

Der obige Code entfernt automatisch Duplikate in einer Liste und druckt auch die Häufigkeit jedes Elements in der ursprünglichen Liste und der Liste ohne Duplikate.

Zwei Fliegen für einen Schuss! XD


0

Dieser Ansatz kann ausprobiert werden, wenn Sie keine Bibliothek verwenden und diese einfach und kurz halten möchten!

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

Für die Aufzeichnung eine funktionale Antwort:

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

Es ist sauberer, wenn Sie auch Nullen zählen:

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

Eine Erklärung:

  • wir beginnen mit einer leeren accListe;
  • Wenn das nächste Element evon Lkleiner als die Größe von ist acc, aktualisieren wir nur dieses Element: v+(i==e)bedeutet, v+1wenn der Index ivon accdas aktuelle Element ist e, andernfalls der vorherige Wertv ;
  • Wenn das nächste Element evon Lgrößer oder gleich der Größe von ist acc, müssen wir es erweitern acc, um das neue zu hosten 1.

Die Elemente müssen nicht sortiert werden ( itertools.groupby). Sie erhalten seltsame Ergebnisse, wenn Sie negative Zahlen haben.


0

Ich habe einen anderen Weg gefunden, dies mit Sets zu tun.

#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

So finden Sie eindeutige Elemente in der Liste

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

Ermitteln der Anzahl eindeutiger Elemente in einem sortierten Array mithilfe des Wörterbuchs

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)

Referenz GeeksforGeeks


-1

Eine weitere Möglichkeit besteht darin, ein Wörterbuch und die Liste.count zu verwenden, unter einer naiven Möglichkeit, dies zu tun.

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.