我有一个频率计数器,用于遍历时间列表并告诉我每个数字出现的频率。首先,我通过一个函数运行它,使用 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 输出发生了什么,它做的一切都是正确的,但它做的是时间,而不是新时间(我们去掉小数点的地方),即使它应该在我们去掉小数点之后.有任何想法吗?谢谢!
最佳答案
问题是itertools.groupby
适用于仅连续的相似项目。它需要经过排序的输入 才能以您期望的方式工作。您也不需要创建中间列表;相反,您可以将 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)
关于python - 频率计数器在我更改之前正在排序列表,更改后应该何时排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53422518/