You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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)

运行后得到的结果和你期望的完全一致:

IDoccupoccupcount
1NaN0
1A1
1NaN1
1B2
1A2
2K1
2NaN1
2L2
2K2
2M3

方法二:向量化操作(高效处理大数据)

如果你的数据集很大,循环遍历会比较慢,推荐用这种向量化的方法,通过标记首次出现的非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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 23:57:49