如何标记Pandas DataFrame分组中缺失值的存在类型
问题分析与修正方案
先构造一个覆盖所有缺失类型的示例DataFrame:
import pandas as pd import numpy as np df = pd.DataFrame({ 'ID': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C', 'D', 'D', 'D', 'E', 'E', 'E', 'E'], 'value': [1, np.nan, 2, 3, np.nan, np.nan, 4, 5, 6, np.nan, np.nan, np.nan, np.nan, np.nan, 7, 8, np.nan] })
原代码的核心问题是未优先处理全NaN组,且未对多类型缺失的组进行统一归类。以下是修正后的代码:
def classify_nan_type(group): mask = group.isna() group_len = len(group) # 优先处理全NaN分组 if mask.all(): return 'full-none' # 定位第一个和最后一个非NaN的位置 first_non_nan = mask.idxmin() # 取第一个非NaN的索引(mask中第一个False的位置) reversed_mask_idx = mask[::-1].idxmin() # 反转后取第一个非NaN的索引 last_non_nan = group_len - reversed_mask_idx - 1 types = [] # 检测开头缺失 if first_non_nan > 0: types.append('leading-none') # 检测结尾缺失 if last_non_nan < group_len - 1: types.append('trailing-none') # 检测中间缺失:首尾非NaN区间内存在NaN if mask.iloc[first_non_nan:last_non_nan+1].any(): types.append('inter-none') # 多类型缺失统一标记为mixed-none,否则取唯一类型 return 'mixed-none' if len(types) >= 2 else types[0] # 按ID分组生成结果字典 result = df.groupby('ID')['value'].apply(classify_nan_type).to_dict() print(result)
关键逻辑说明
- 全NaN优先判断:用
mask.all()直接识别全缺失组,避免后续逻辑误判。 - 高效定位非NaN位置:利用
idxmin()快速找到首尾非NaN的索引,无需遍历整个分组。 - 多类型检测与归类:分别校验开头、结尾、中间的缺失情况,收集所有符合的类型;若存在≥2种类型,统一标记为
mixed-none。
预期输出
运行代码后会得到符合需求的结果:
{ 'A': 'inter-none', 'B': 'leading-none', 'C': 'trailing-none', 'D': 'full-none', 'E': 'mixed-none' }
其中D组(全NaN)、E组(首尾均有NaN)的标记完全符合要求。
内容的提问来源于stack exchange,提问作者VERBOSE
相关产品推荐
相关产品推荐

