我有一个频率计数器,用于遍历时间列表,并告诉我每个数字出现的频率。首先,我通过一个函数运行它,以使用int()
删除小数。我用底部的打印语句进行检查,效果很好。但是由于某种原因,即使频率发生在我使用int()
更改值之后。这是我的代码,我将给出一些输出。
from itertools import groupby
times = [1.23, 1.23, 2.56, 1.23, 1.23, 1.23, 1.23, 1.5, 4.32, 5.3, 2.5, 5.7, 3.4, 8.9, 8.9, 8.9]
newtimes = []
lentimes = len(times)
for time in times:
#Rounds down every time
time = int(time)
#Adds time to new list
newtimes.append(time)
setTimes = list(set(newtimes))
freqlist = [len(list(group)) for key, group in groupby(newtimes)]
print(newtimes)
print(lentimes)
print(setTimes)
print("Freqlist is " + str(freqlist))
输出如下:
[1, 1, 2, 1, 1, 1, 1, 1, 4, 5, 2, 5, 3, 8, 8, 8]
16
[1, 2, 3, 4, 5, 8]
Freqlist is [2, 1, 5, 1, 1, 1, 1, 1, 3]
花了我一段时间才能弄清楚freqlist输出的结果,它做的一切正确,但是它是在执行时间,而不是newtimes(在其中删除小数点),即使应该在删除小数点后。有任何想法吗?谢谢!
答案 0 :(得分:1)
问题是itertools.groupby
仅适用于连续相似的物品。它需要经过排序的 input 才能以您期望的方式工作。您也不需要创建中介列表。相反,您可以将sum
与生成器表达式一起使用:
freqlist = [sum(1 for _ in group) for key, group in groupby(sorted(newtimes))]
排序需要O( n log n )时间。对于O( n )解决方案,可以使用collections.Counter
:
from collections import Counter
d = Counter(map(int, times))
Counter({1: 7, 2: 2, 4: 1, 5: 2, 3: 1, 8: 3})
然后,如果需要,可以在按键排序后提取列表中的值:
keys, values = zip(*sorted(d.items()))
print(values)
(7, 2, 1, 1, 2, 3)