Pandas按分组累计统计唯一(b,c)键值对数量的实现求助
解决按分组累计统计唯一(b,c)键值对数量的问题
先还原你的数据场景,你的DataFrame定义如下:
import pandas as pd df = pd.DataFrame({ "a": [1, 1, 1, 2, 2,3], "b": ["a", "a", "c", "a", "d","a"], "c": ["2", "3", "4", "2", "3","2"] })
对应的表格:
| a | b | c | |
|---|---|---|---|
| 0 | 1 | 'a' | '2' |
| 1 | 1 | 'a' | '3' |
| 2 | 1 | 'c' | '4' |
| 3 | 2 | 'a' | '2' |
| 4 | 2 | 'd' | '3' |
| 5 | 3 | 'a' | '2' |
你的需求很明确:针对a的每个分组,统计截至当前分组的所有唯一(b,c)键值对数量,预期输出[3,4,4]——分组1有3个唯一对,分组1+2合计4个,加上分组3后没有新增唯一对,所以还是4个。
你尝试用groupby+expanding+nunique没成功,其实不用这么复杂,这里给你两种简单易懂的实现方式:
方法一:基于标记累加(Pandas原生操作)
这种方法利用Pandas的重复值标记和分组累加功能,代码简洁高效:
# 第一步:标记每个(b,c)对是否是首次出现(True表示首次) df['is_unique'] = ~df[['b', 'c']].duplicated() # 第二步:按a分组累计求和,再取每个分组的最后一个值(即截至该分组的累计唯一数) result = df.groupby('a')['is_unique'].cumsum().groupby(df['a']).last().tolist() print(result) # 输出: [3, 4, 4]
步骤解释:
~df[['b','c']].duplicated():duplicated()会返回每行是否是重复的(b,c)对(True=重复),取反后is_unique列就标记了每个(b,c)对的首次出现行。groupby('a')['is_unique'].cumsum():按a分组后,对is_unique做累加,这样每行的值就是截至当前行的累计唯一(b,c)数量。.groupby(df['a']).last():每个a分组的最后一行对应的累加值,就是截至该分组的总唯一数,最后转成列表就是你要的结果。
方法二:集合遍历法(直观易理解)
如果你更喜欢逻辑清晰的方式,可以用集合自动去重的特性,遍历每个分组逐步统计:
# 初始化空集合存储唯一(b,c)对 unique_pairs = set() result = [] # 遍历每个a的分组 for _, group_data in df.groupby('a'): # 将当前分组的所有(b,c)对加入集合(集合自动去重) unique_pairs.update(zip(group_data['b'], group_data['c'])) # 记录当前集合的大小(即截至当前分组的累计唯一数) result.append(len(unique_pairs)) print(result) # 输出: [3, 4, 4]
这种方法逻辑非常直观:每处理一个a的分组,就把该组所有(b,c)对加入集合,集合会自动忽略已经存在的对,然后每次记录集合的长度,就是截至当前分组的累计唯一数量。
内容的提问来源于stack exchange,提问作者Binyamin Even
相关产品推荐
相关产品推荐

