如何计算一个无序列表中元素的频率?

给定一个无序的值列表,比如

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

我怎样才能得到出现在列表中的每个值的频率,就像这样?

# `a` has 4 instances of `1`, 4 of `2`, 2 of `3`, 1 of `4,` 2 of `5`
b = [4, 4, 2, 1, 2] # expected output
652265 次浏览

对于您的第一个问题,迭代列表并使用字典跟踪元素的存在。

对于你的第二个问题,只需使用集合操作符。

通过遍历列表并计算它们,手动计算出现的数量,使用collections.defaultdict跟踪到目前为止所看到的内容:

from collections import defaultdict


appearances = defaultdict(int)


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

计算元素的频率可能最好使用字典:

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

要删除重复项,请使用set:

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

如果列表已经排序,你可以使用itertools标准库中的groupby(如果不是,你可以先对它排序,尽管这需要O(nlgn)时间):

from itertools import groupby


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

输出:

[4, 4, 2, 1, 2]

在Python 2.7+中,可以使用集合。计数器来计数项

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

在Python 2.7(或更新版本)中,您可以使用collections.Counter:

>>> import collections
>>> a = [5, 1, 2, 2, 4, 3, 1, 2, 3, 1, 1, 5, 2]
>>> counter = collections.Counter(a)
>>> counter
Counter({1: 4, 2: 4, 5: 2, 3: 2, 4: 1})
>>> counter.values()
dict_values([2, 4, 4, 1, 2])
>>> counter.keys()
dict_keys([5, 1, 2, 4, 3])
>>> counter.most_common(3)
[(1, 4), (2, 4), (5, 2)]
>>> dict(counter)
{5: 2, 1: 4, 2: 4, 4: 1, 3: 2}
>>> # Get the counts in order matching the original specification,
>>> # by iterating over keys in sorted order
>>> [counter[x] for x in sorted(counter.keys())]
[4, 4, 2, 1, 2]

如果你使用的是Python 2.6或更老版本,你可以下载一个实现在这里

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]

这个答案更加明确

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}
#!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()

还有另一种不使用集合的算法解决方案:

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

我将简单地以以下方式使用scipy.stats.itemfreq:

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]

你可以在这里查看文档:http://docs.scipy.org/doc/scipy-0.16.0/reference/generated/scipy.stats.itemfreq.html

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
str1='the cat sat on the hat hat'
list1=str1.split();
list2=str1.split();


count=0;
m=[];


for i in range(len(list1)):
t=list1.pop(0);
print t
for j in range(len(list2)):
if(t==list2[j]):
count=count+1;
print count
m.append(count)
print m
count=0;
#print m

还有一种方法是使用字典和列表。数数,下面一种幼稚的做法。

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)

你可以这样做:

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

第一个数组是值,第二个数组是具有这些值的元素的数量。

所以如果你想要得到一个数字数组,你应该使用这个:

np.unique(a, return_counts=True)[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)

您可以使用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])

上面的代码自动删除列表中的重复项,并打印原始列表和没有重复项的列表中每个元素的频率。

一枪双鸟!X维

如果您不想使用任何库并保持简单和简短,可以尝试这种方法!

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]
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'])
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行代码中从文本文件单词生成一个frequency . dict

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

我迟到了,但这也有用,也会帮助到其他人:

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]

郑重声明,一个实用的答案:

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

如果你把0也算进去,那就更简洁了:

>>> 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列表开始;
  • 如果L的下一个元素e小于acc的大小,我们只更新这个元素:如果acc的索引i是当前元素e,则v+(i==e)表示v+1,否则之前的值v;
  • 如果L的下一个元素e大于或等于acc的大小,我们必须展开acc以容纳新的1

元素不需要排序(itertools.groupby)。如果是负数,结果会很奇怪。

下面是另一个简洁的替代方法,使用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))}

结果

format: {value: num_of_occurencies}
{1: 4, 2: 4, 3: 2, 4: 1, 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)转换为List,并由相同的变量a引用

输出

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

简单的解决方法就是用字典。

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

另一种方法是使用较重但功能强大的库——NLTK。

import nltk


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

我找到了另一种方法,使用集合。

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

对于一个无序列表,你应该使用:

[a.count(el) for el in set(a)]

输出为

[4, 4, 2, 1, 2]

假设我们有一个列表:

fruits = ['banana', 'banana', 'apple', 'banana']

我们可以在列表中找出每种水果的数量,像这样:

import numpy as np
(unique, counts) = np.unique(fruits, return_counts=True)
{x:y for x,y in zip(unique, counts)}

结果:

{'banana': 3, 'apple': 1}
a = [1,1,1,1,2,2,2,2,3,3,4,5,5]
counts = dict.fromkeys(a, 0)
for el in a: counts[el] += 1
print(counts)
# {1: 4, 2: 4, 3: 2, 4: 1, 5: 2}