Python/Pandas实现ID分组累计计数(ID变化时重置为1)
Pythonic实现按ID分组累计计数的方案
嘿,这个需求用Python实现的话,有几种非常贴合Python风格的方案,我给你梳理一下:
方案一:使用Pandas(最推荐,适合表格数据)
如果你的数据是表格形式(像Excel那样),用Pandas处理绝对是最Pythonic的选择——它的groupby配合cumcount()方法正好就是为这种分组累计场景设计的,一行代码就能搞定:
import pandas as pd # 构造示例数据 data = { "ID": [100001, 100001, 100001, 100001, 100002, 100002, 100003, 100003, 100003, 100003] } df = pd.DataFrame(data) # 按ID分组后,对每组元素从0开始计数,加1后得到从1开始的累计值 df["CUM_FREQ"] = df.groupby("ID").cumcount() + 1 print(df)
运行后输出的结果和你给出的示例完全一致:
ID CUM_FREQ 0 100001 1 1 100001 2 2 100001 3 3 100001 4 4 100002 1 5 100002 2 6 100003 1 7 100003 2 8 100003 3 9 100003 4
方案二:纯Python原生实现(用itertools.groupby)
如果不想依赖第三方库,用Python标准库的itertools.groupby也能简洁实现,前提是你的ID列表是连续分组的(和示例数据一样):
from itertools import groupby id_list = [100001, 100001, 100001, 100001, 100002, 100002, 100003, 100003, 100003, 100003] result = [] # 按相同ID分组,对每个组生成从1开始的计数 for id_val, group in groupby(id_list): group_size = len(list(group)) result.extend([(id_val, i+1) for i in range(group_size)]) # 格式化输出 print("ID\tCUM_FREQ") for item in result: print(f"{item[0]}\t{item[1]}")
注意:如果你的ID列表不是连续分组的(比如中间穿插了其他ID后又回到之前的ID),需要先对列表排序:
id_list.sort(),否则groupby会把不连续的相同ID当成不同组。
方案三:手动遍历(对应Excel公式逻辑)
如果你想完全对应Excel里IF(C3=C2,B2+1,1)的逻辑,手动遍历也是一种直观的方式,逻辑和Excel公式完全一致:
id_list = [100001, 100001, 100001, 100001, 100002, 100002, 100003, 100003, 100003, 100003] cum_freq = [] prev_id = None current_count = 1 for id_val in id_list: # 如果当前ID和上一个不同,重置计数 if id_val != prev_id: prev_id = id_val current_count = 1 cum_freq.append(current_count) current_count += 1 # 配对输出 print("ID\tCUM_FREQ") for id_val, freq in zip(id_list, cum_freq): print(f"{id_val}\t{freq}")
这种方式适合理解底层逻辑,但代码量比前两种多,处理大数据量的效率也不如Pandas。
内容的提问来源于stack exchange,提问作者Rahul Sattar
相关产品推荐
相关产品推荐

