如何在Python中按组按年份累计计算Type列的唯一值?
问题描述
给定包含Group、Year、Type列的DataFrame,需要按Group分组,以Year为顺序累计统计截至当前年份的Type列唯一值数量,生成名为Want的新列。
输入DataFrame
| Group | Year | Type |
|---|---|---|
| A | 1998 | red |
| A | 1998 | blue |
| A | 2002 | red |
| A | 2005 | blue |
| A | 2008 | blue |
| A | 2008 | yello |
| B | 1998 | red |
| B | 2001 | red |
| B | 2003 | red |
| C | 1996 | red |
| C | 2002 | orange |
| C | 2002 | red |
| C | 2012 | blue |
| C | 2012 | yello |
期望输出DataFrame
| Group | Year | Type | Want |
|---|---|---|---|
| A | 1998 | red | 2 |
| A | 1998 | blue | 2 |
| A | 2002 | red | 2 |
| A | 2005 | blue | 2 |
| A | 2008 | blue | 3 |
| A | 2008 | yello | 3 |
| B | 1998 | red | 1 |
| B | 2001 | red | 1 |
| B | 2003 | red | 1 |
| C | 1996 | red | 1 |
| C | 2002 | orange | 2 |
| C | 2002 | red | 2 |
| C | 2012 | blue | 4 |
| C | 2012 | yello | 4 |
规则说明
- 同一
Group内,每个Year对应的所有行,Want值相同,为从该组最早年份到当前年份的所有Type唯一值总数。 - 不同
Group的年份分布独立计算,互不影响。
解决方案
使用Pandas实现,步骤如下:
- 提取每个
Group内(Year, Type)的唯一组合,避免重复统计同一年份的相同Type; - 对每个
Group按Year升序排列,计算累计到当前年份的唯一Type集合大小; - 将计算结果合并回原DataFrame,匹配对应
Group和Year的Want值。
代码实现
import pandas as pd # 构造输入DataFrame(实际使用时可替换为你的数据) df = pd.DataFrame({ 'Group': ['A','A','A','A','A','A','B','B','B','C','C','C','C','C'], 'Year': [1998,1998,2002,2005,2008,2008,1998,2001,2003,1996,2002,2002,2012,2012], 'Type': ['red','blue','red','blue','blue','yello','red','red','red','red','orange','red','blue','yello'] }) # 步骤1:提取每个Group内(Year, Type)的唯一组合,并按Year排序 grouped_unique = df.groupby('Group').apply( lambda x: x[['Year', 'Type']].drop_duplicates().sort_values('Year') ).reset_index(drop=True) # 步骤2:计算每个Group累计到当前年份的唯一Type数量 grouped_unique['cumulative_types'] = grouped_unique.groupby('Group')['Type'].expanding().apply( lambda x: set(x) ).reset_index(level=0, drop=True) grouped_unique['Want'] = grouped_unique['cumulative_types'].str.len() # 步骤3:合并结果到原DataFrame result = df.merge(grouped_unique[['Group', 'Year', 'Want']], on=['Group', 'Year'], how='left') # 查看最终结果 print(result)
代码说明
drop_duplicates():确保同一年份的同一Type只被统计一次;expanding().apply(lambda x: set(x)):对每个Group的Type列进行累计扩展,每次迭代收集到当前位置的所有唯一Type;merge():将计算好的Want值映射回原DataFrame,保证同一Group和Year的所有行有相同的Want值。
内容的提问来源于stack exchange,提问作者leilei
相关产品推荐
相关产品推荐

