如何在Pandas中按分组去除缺失值?附R data.table参考实现
Pandas实现同组非缺失值合并的最优方案
需求说明
给定输入数据集:
participant trials Correct_Choice Opt_in 1 1 NaN 1 1 1 1 NaN 2 1 NaN 1 2 1 0 NaN
期望输出:将participant(参与者)和trials(试次)相同的行合并,保留各字段的非缺失值,得到如下结果:
participant trials Correct_Choice Opt_in 1 1 1 1 2 1 0 1
已知R语言中使用data.table的实现代码:
setDT(df)[, lapply(.SD, na.omit) , by = list(participant,trials)]
附R示例数据集(字段对应中文:participant=参与者ID,block=区块,trials=试次,opt_in.keys=选择参与按键,correct_chosen=是否选择正确):
structure(list(参与者ID = c("612550d21d30a44cb0d2d579", "612550d21d30a44cb0d2d579", "612550d21d30a44cb0d2d579", "612550d21d30a44cb0d2d579", "612550d21d30a44cb0d2d579", "612550d21d30a44cb0d2d579", "612550d21d30a44cb0d2d579", "612550d21d30a44cb0d2d579", "612550d21d30a44cb0d2d579", "612550d21d30a44cb0d2d579", "612550d21d30a44cb0d2d579", "612550d21d30a44cb0d2d579", "612550d21d30a44cb0d2d579", "612550d21d30a44cb0d2d579", "612550d21d30a44cb0d2d579", "612550d21d30a44cb0d2d579", "612550d21d30a44cb0d2d579", "612550d21d30a44cb0d2d579"), 区块 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), 试次 = c(0L, 0L, 0L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L), 选择参与按键 = c(1, NA, NA, 1, NA, NA, NA, 1, NA, NA, 1, NA, NA, NA, 1, NA, NA, NA), 是否选择正确 = c(NA, 1L, NA, NA, 1L, NA, NA, NA, 1L, NA, NA, 1L, NA, NA, NA, 1L, NA, NA)), row.names = c(NA, -18L), class = c("data.table", "data.frame"), .internal.selfref = <pointer: 0x7fd1a20102e0>)
Pandas实现方法
最优方案:分组聚合提取非缺失值
该方案完全对应R data.table的逻辑,按分组键对每个列执行去缺失值操作后取唯一有效值,直观且性能优异:
import pandas as pd # 加载示例数据 df = pd.DataFrame({ 'participant': [1, 1, 2, 2], 'trials': [1, 1, 1, 1], 'Correct_Choice': [pd.NA, 1, pd.NA, 0], 'Opt_in': [1, pd.NA, 1, pd.NA] }) # 核心代码 result = df.groupby(['participant', 'trials'], as_index=False).agg(lambda x: x.dropna().iloc[0])
备选方案:填充缺失值后取首行
适合数据量较大的场景,通过组内双向填充缺失值,再取每组第一行:
result = df.groupby(['participant', 'trials']) \ .apply(lambda x: x.bfill().ffill().head(1)) \ .reset_index(drop=True)
简洁方案:利用first_valid_index(Pandas 1.3+)
通过定位每个列的第一个有效索引来提取值:
result = df.groupby(['participant', 'trials'], as_index=False).agg(lambda x: x.loc[x.first_valid_index()])
内容的提问来源于stack exchange,提问作者user15791858
相关产品推荐
相关产品推荐

