如何在Python的Pandas DataFrame中按组逐步统计列的非NaN唯一值数量
嘿,这个逐步累加分组内非NaN唯一值的需求我刚好处理过,给你两个实用的解决方案!
方法一:自定义遍历函数(直观易懂)
这种方法通过逐行遍历每个分组的occup列,用集合记录已经出现过的非NaN值,每一步都统计集合的大小,完美匹配你的逐步累加需求:
import pandas as pd import numpy as np # 构建你的示例数据 df = pd.DataFrame({ 'ID': [1,1,1,1,1,2,2,2,2,2], 'occup': [np.nan, 'A', np.nan, 'B', 'A', 'K', np.nan, 'L', 'K', 'M'] }) def cumulative_unique_counter(series): seen_values = set() count_list = [] for val in series: # 只把非NaN值加入集合 if pd.notna(val): seen_values.add(val) # 记录当前已出现的唯一非NaN值数量 count_list.append(len(seen_values)) return pd.Series(count_list, index=series.index) # 按ID分组应用自定义函数,生成新列 df['occupcount'] = df.groupby('ID')['occup'].apply(cumulative_unique_counter)
运行后得到的结果和你期望的完全一致:
| ID | occup | occupcount |
|---|---|---|
| 1 | NaN | 0 |
| 1 | A | 1 |
| 1 | NaN | 1 |
| 1 | B | 2 |
| 1 | A | 2 |
| 2 | K | 1 |
| 2 | NaN | 1 |
| 2 | L | 2 |
| 2 | K | 2 |
| 2 | M | 3 |
方法二:向量化操作(高效处理大数据)
如果你的数据集很大,循环遍历会比较慢,推荐用这种向量化的方法,通过标记首次出现的非NaN值,再按组累加计数:
# 标记:非NaN且是该分组内首次出现的值 df['is_unique_new'] = df.groupby('ID')['occup'].apply(lambda x: ~x.duplicated() & pd.notna(x)) # 按组累加标记,得到逐步的唯一值数量 df['occupcount'] = df.groupby('ID')['is_unique_new'].cumsum()
为什么之前的transform('nunique')不行?
你之前尝试的df.groupby(["ID"])['occup'].transform('nunique')会直接返回每个分组的全局唯一值总数,比如ID=1的所有行都会得到2,ID=2的所有行得到3,无法实现逐行累加的效果,而上面两种方法都是针对每行逐步统计的。
内容的提问来源于stack exchange,提问作者Vik Jagger
相关产品推荐
相关产品推荐

