如何获取pandas分组下方行的值填充分组首行空值字段
Pandas分组首行空值填充方案
问题描述
对Pandas DataFrame完成排序、分组操作后,需按以下规则处理分组首行的空值:
- 仅当分组内排名最高的首行对应字段为空(
None/NaN),且同组下方行存在非空条目时执行填充 - 填充值选用该分组内对应字段出现频次最高的非空值
- 若组内对应字段无有效非空值,保留原空值
- 最终输出仅保留各分组的首行记录
测试用例
输入DataFrame构造代码:
import pandas df = pandas.DataFrame({'ENr': ['EDFT2Z', 'EDFT2Z', 'EDFT2Z', 'EDFT2Z', 'EDFTDA', 'EDFTDA'], 'Rnk': [1, 2, 3, 4, 1, 2], 'StA': [None, 'W', 'F', 'F', None, None], 'Val': ['abc', 'def', 'ghi', 'jkl', 'mno', 'pqr']})
按Rnk字段升序排序后,按ENr分组得到的分组结构:
ENr Rnk StA Val ------------------------ 0 EDFT2Z 1 None abc \ 1 EDFT2Z 2 W def | ENr=EDFT2Z 分组 2 EDFT2Z 3 F ghi | 3 EDFT2Z 4 F jkl / ------------------------ 4 EDFTDA 1 None mno \ ENr=EDFTDA 分组 5 EDFTDA 2 None pqr /
用例预期处理逻辑:
- EDFT2Z分组首行StA字段为空,组内非空值中
F出现2次、频次最高,因此首行StA替换为F - EDFTDA分组首行StA字段为空,组内无StA非空值,保留
None
预期输出结果:
ENr Rnk StA Val ------------------------ 0 EDFT2Z 1 F abc ------------------------ 4 EDFTDA 1 None mno
实现代码
# 1. 按排名字段排序,保证分组首行为排名最高的记录 df = df.sort_values('Rnk').reset_index(drop=True) # 2. 定义函数取序列内最高频非空值,无有效非空值返回None def top_freq_non_null(s): non_null = s.dropna() return non_null.value_counts().index[0] if len(non_null) > 0 else None # 3. 分组计算每个组对应字段的最高频非空值 group_fill_val = df.groupby('ENr')['StA'].transform(top_freq_non_null) # 4. 标记分组首行位置,仅对首行的空值执行填充 first_row_mask = ~df.duplicated(subset='ENr', keep='first') fill_mask = first_row_mask & df['StA'].isna() df.loc[fill_mask, 'StA'] = group_fill_val[fill_mask] # 5. 提取各分组首行得到最终结果 result = df[first_row_mask]
运行后result的输出与预期完全一致。
内容的提问来源于stack exchange,提问作者gemixl
相关产品推荐
相关产品推荐

