Answers:
注意:您应该在使用之前对列表进行排序groupby
。
如果列表是有序列表,则可以groupby
从itertools
包中使用。
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方法的关系
sum(1 for _ in group)
。
[(key, len(list(group))) for key, group in groupby(a)]
或{key: len(list(group)) for key, group in groupby(a)}
@buhtz
在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或更早版本,则可以在此处下载。
collections.Counter
是的子类dict
。您可以像普通字典一样使用它。但是,如果您确实想要字典,则可以使用将其转换为字典dict(counter)
。
Python 2.7+引入了Dictionary Comprehension。从列表中构建字典将使您获得计数并消除重复项。
>>> 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()
做了完整的横移中的每个元素a
,使之成为一个O(N ^ 2)二次型的方法。collections.Counter()
是更有效的,因为它以线性时间(O(N))进行计数。从数量上讲,这意味着对于长度为1000的列表,此方法将执行1百万步,而对于长度为1000的列表,则仅执行1000步Counter()
,而Counter对于列表中的一百万个项目仅需要10 ^ 6步,依此类推
a.count()
完全使用它的恐惧使在那儿使用电视机的效率相形见war 。
计算出场次数:
from collections import defaultdict
appearances = defaultdict(int)
for curr in a:
appearances[curr] += 1
删除重复项:
a = set(a)
Counter
可以使用多种数字类型,包括float
或Decimal
,而不仅仅是int
。
在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]
计算元素的频率最好用字典来完成:
b = {}
for item in a:
b[item] = b.get(item, 0) + 1
要删除重复项,请使用一组:
a = list(set(a))
defaultdict
。
b = {k:0 for k in a}
?
你可以这样做:
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]
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
在这种情况下,使用列表非常昂贵并且是不必要的。
我将以以下方式简单地使用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/generation/scipy.stats.itemfreq.html
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)
输出量
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]))
max(d.values())
在最后一个循环中不会改变。不要在循环中计算它,而要在循环之前计算它。
#!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()
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]
我正在使用Counter生成频率。1行代码中来自文本文件单词的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])
尽管使用了一个更重但功能强大的库NLTK,但这也是另一种方法。
import nltk
fdist = nltk.FreqDist(a)
fdist.values()
fdist.most_common()
在不使用集合的情况下使用另一种算法的另一种解决方案:
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
您可以使用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
记录下来,一个功能性的答案:
>>> 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
列表开始;e
的L
比规模下acc
,我们只需更新这个元素:v+(i==e)
手段v+1
如果索引i
的acc
是当前元素e
,否则,前值v
;e
的L
大于或等于的大小acc
,我们必须扩大acc
,以容纳新的1
。元素不必排序(itertools.groupby
)。如果数字为负,则会得到怪异的结果。
找到了另一种使用集合的方法。
#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 = [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)