如何用GroupBy统计列表中相同a、b、c属性值的对象数量
解决1000万条类实例的(a,b,c)组合统计问题
我完全懂你的需求——手里攒了1000万条自定义类的实例,每个实例有a、b、c三个属性(取值0-24),想要像SQL里GROUP BY a,b,c那样统计每个组合的出现次数,却一直没找到靠谱的实现方式。别着急,这里有几种高效且易上手的方案,专门适配你这种大数据量的场景:
方法一:用collections.Counter(最简洁高效)
Python标准库的Counter就是为这类计数场景量身定做的,它能自动帮你统计可哈希元素的出现次数,而且处理1000万条数据的性能也很可观。
步骤示例:
假设你的类和实例列表是这样的:
from random import randint class MyData: def __init__(self, a, b, c): self.a = a self.b = b self.c = c # 你的1000万条实例列表(这里用模拟数据举例) instances = [MyData(randint(0,24), randint(0,24), randint(0,24)) for _ in range(10_000_000)]
统计代码:
from collections import Counter # 用生成器表达式逐个提取(a,b,c)三元组(避免一次性创建大列表占内存) counter = Counter((obj.a, obj.b, obj.c) for obj in instances) # 转换成你需要的「(a,b,c) + 次数」列表,还可以按a/b/c排序 result_list = sorted(counter.items(), key=lambda x: (x[0][0], x[0][1], x[0][2])) # 控制台输出结果 for (a, b, c), count in result_list: print(f"a={a}, b={b}, c={c} | 出现次数:{count}")
方法二:手动用字典计数(更灵活)
如果你需要对计数过程做自定义控制,也可以手动用字典实现,原理和Counter一致,但能让你更清楚每一步的逻辑:
count_dict = {} for obj in instances: # 把(a,b,c)组合成元组作为字典的键(元组是可哈希的,能被字典识别) key = (obj.a, obj.b, obj.c) # 计数:存在就加1,不存在就初始化为1 count_dict[key] = count_dict.get(key, 0) + 1 # 后续的排序和输出和方法一完全一致 result_list = sorted(count_dict.items(), key=lambda x: (x[0][0], x[0][1], x[0][2])) for (a, b, c), count in result_list: print(f"a={a}, b={b}, c={c} | 出现次数:{count}")
为什么你之前可能失败?
大概率是没把三个属性组合成可哈希的键——比如如果你用列表[obj.a, obj.b, obj.c]当字典键,会直接报错,因为列表是不可哈希的。而元组(obj.a, obj.b, obj.c)是可哈希的,完美适配字典的键要求。
另外,如果之前用了嵌套循环去逐个统计,那效率会极低(时间复杂度O(n²)),1000万条数据根本跑不完,而上面两种方法都是O(n)的时间复杂度,速度快得多。
内容的提问来源于stack exchange,提问作者ImtehQ
相关产品推荐
相关产品推荐

