Necesito encontrar la frecuencia de los elementos en una lista desordenada
a = [1,1,1,1,2,2,2,2,3,3,4,5,5]
salida->
b = [4,4,2,1,2]
También quiero eliminar los duplicados de un
a = [1,2,3,4,5]
Necesito encontrar la frecuencia de los elementos en una lista desordenada
a = [1,1,1,1,2,2,2,2,3,3,4,5,5]
salida->
b = [4,4,2,1,2]
También quiero eliminar los duplicados de un
a = [1,2,3,4,5]
Respuestas:
Nota: Debe ordenar la lista antes de usar groupby
.
Se puede utilizar groupby
de itertools
paquete si la lista es una lista ordenada.
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)]
Salida:
[4, 4, 2, 1, 2]
groupby
. Sin embargo, me pregunto acerca de su eficiencia frente al enfoque dict
sum(1 for _ in group)
.
[(key, len(list(group))) for key, group in groupby(a)]
o {key: len(list(group)) for key, group in groupby(a)}
@buhtz
En Python 2.7 (o más reciente), puede usar 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)]
Si está utilizando Python 2.6 o anterior, puede descargarlo aquí .
collections.Counter
es una subclase de dict
. Puede usarlo de la misma manera que lo haría con un dict normal. Sin embargo, si realmente quieres un dict, puedes convertirlo a un dict usando dict(counter)
.
Python 2.7+ presenta la comprensión del diccionario. Construir el diccionario a partir de la lista le dará el recuento y eliminará los duplicados.
>>> 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]
{x:a.count(x) for x in set(a)}
a.count()
realiza un recorrido completo para cada elemento en a
, haciendo de este un enfoque cuadrádico O (N ^ 2). collections.Counter()
es mucho más eficiente porque cuenta en tiempo lineal (O (N)). En números, esto significa que este enfoque se ejecutarán 1 millón de pasos para una lista de longitud 1000, frente a sólo 1.000 pasos con Counter()
, 10 ^ 12 pasos, donde sólo el 10 ^ 6 son necesarios por el contador por un millón de elementos de una lista, etc.
a.count()
completamente eclipsa la eficiencia de haber usado un set allí.
Para contar el número de apariciones:
from collections import defaultdict
appearances = defaultdict(int)
for curr in a:
appearances[curr] += 1
Para eliminar duplicados:
a = set(a)
Counter
puede usar múltiples tipos numéricos, incluidos float
o Decimal
no solo int
.
En Python 2.7+, puede usar colecciones. Contador para contar elementos
>>> 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]
Contar la frecuencia de los elementos probablemente se haga mejor con un diccionario:
b = {}
for item in a:
b[item] = b.get(item, 0) + 1
Para eliminar los duplicados, use un conjunto:
a = list(set(a))
defaultdict
.
b = {k:0 for k in a}
:?
Aquí hay otra alternativa sucinta itertools.groupby
que también funciona para entradas no ordenadas:
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))}
resultados
{1: 4, 2: 4, 3: 2, 4: 1, 5: 2}
Puedes hacerlo:
import numpy as np
a = [1,1,1,1,2,2,2,2,3,3,4,5,5]
np.unique(a, return_counts=True)
Salida:
(array([1, 2, 3, 4, 5]), array([4, 4, 2, 1, 2], dtype=int64))
La primera matriz son valores, y la segunda matriz es el número de elementos con estos valores.
Entonces, si desea obtener solo una matriz con los números, debe usar esto:
np.unique(a, return_counts=True)[1]
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'])
seta = set(a)
b = [a.count(el) for el in seta]
a = list(seta) #Only if you really want it.
count
es ridículamente costoso y no se requiere en este escenario.
Simplemente usaría scipy.stats.itemfreq de la siguiente manera:
from scipy.stats import itemfreq
a = [1,1,1,1,2,2,2,2,3,3,4,5,5]
freq = itemfreq(a)
a = freq[:,0]
b = freq[:,1]
Puede consultar la documentación aquí: http://docs.scipy.org/doc/scipy-0.16.0/reference/generated/scipy.stats.itemfreq.html
Esta respuesta es más explícita.
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}
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
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)
Salida
D:\MLrec\venv\Scripts\python.exe D:/MLrec/listgroup.py
[4, 4, 2, 1, 2]
[1, 2, 3, 4, 5]
Solución simple usando un diccionario.
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())
no cambiará en el último bucle. No lo calcules en el ciclo, cómpralo antes del ciclo.
#!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()
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)
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]
Para eliminar duplicados y mantener el orden:
list(dict.fromkeys(get_count(a)))
>>>[4, 2, 1]
Estoy usando Counter para generar una frecuencia. dict de palabras de archivo de texto en 1 línea de código
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])
Otro enfoque para hacer esto, aunque mediante el uso de una biblioteca más pesada pero poderosa, NLTK.
import nltk
fdist = nltk.FreqDist(a)
fdist.values()
fdist.most_common()
Otra solución más con otro algoritmo sin usar colecciones:
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
Puede usar la función integrada proporcionada en 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])
El código anterior elimina automáticamente los duplicados en una lista y también imprime la frecuencia de cada elemento en la lista original y la lista sin duplicados.
¡Dos pájaros para un disparo! XD
¡Este enfoque se puede probar si no desea utilizar ninguna biblioteca y mantenerla simple y breve!
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]
Para el registro, una respuesta funcional:
>>> 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 más limpio si también cuentas ceros:
>>> 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]
Una explicación:
acc
lista vacía ;e
de L
es menor que el tamaño de acc
, simplemente actualizamos este elemento: v+(i==e)
significa v+1
si el índice i
de acc
es el elemento actual e
, de lo contrario, el valor anterior v
;e
de L
es mayor o igual al tamaño de acc
, tenemos que expandirnos acc
para alojar el nuevo 1
.Los elementos no tienen que ser ordenados ( itertools.groupby
). Obtendrás resultados extraños si tienes números negativos.
Encontré otra forma de hacerlo, usando conjuntos.
#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)
Para encontrar elementos únicos en la lista
a = [1,1,1,1,2,2,2,2,3,3,4,5,5]
a = list(set(a))
Para encontrar el recuento de elementos únicos en una matriz ordenada usando el diccionario
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 de referencia
Una forma más es usar un diccionario y list.count, debajo de una forma ingenua de hacerlo.
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)