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

Python:按参与者向前填充多时间点数据集的BPMEDS缺失值

问题需求

我有一个存储健康数据的Python DataFrame,每个参与者对应时间点1、2、3。其中BPMEDS列存在缺失值,多数缺失发生在最后一个时间点(可能是1、2或3),缺失值的上方是该参与者最后有有效值的行。例如RANDID为16799的参与者在period3的BPMEDS为NaN,但period2的值为0.0,我希望将该参与者最后可用的值填充到缺失行中;若仅存在period1且BPMEDS为空,则暂时忽略该情况。

尝试以下代码时出现ValueError和TypeError:

for ind in df.index:
    if df['PERIOD'][ind] != '1':
       df['BPMEDS'][ind] = df.groupby(['RANDID']).fillna(method='ffill')

数据集示例:

RANDID  BPMEDS  PERIOD
26   16799     0.0       1
27   16799     0.0       2
28   16799     NaN       3
29   19304     0.0       1
30   20375     0.0       1
31   20375     0.0       2
32   23727     1.0       1
解决方案

原代码问题分析

  • 循环遍历索引的方式效率低下,且直接赋值df['BPMEDS'][ind]容易触发SettingWithCopyWarning,导致赋值失效
  • df.groupby(['RANDID']).fillna(method='ffill')返回的是完整的分组填充后DataFrame,无法直接赋值给单个元素,这是报错的核心原因

正确实现代码

import pandas as pd

# 1. 按参与者分组,对BPMEDS列做组内前向填充
df['BPMEDS'] = df.groupby('RANDID')['BPMEDS'].ffill()

# 2. 还原仅period1且原BPMEDS为空的行
# 标记每个参与者的时间点数量
df['period_count'] = df.groupby('RANDID')['PERIOD'].transform('count')
# 筛选需还原的行:仅1个时间点、时间点为1、原BPMEDS为空
mask = (df['period_count'] == 1) & (df['PERIOD'] == 1) & (df['BPMEDS'].isna())
df.loc[mask, 'BPMEDS'] = pd.NA

# 清理临时列(可选)
df = df.drop('period_count', axis=1)

代码说明

  • groupby('RANDID')['BPMEDS'].ffill()会在每个参与者的行内,自动用前一行的有效值填充后续的NaN,完美匹配“用最后可用值填充缺失”的需求(比如示例中16799的period3 NaN会被填充为0.0)
  • 第二步的筛选逻辑精准定位到“仅period1且BPMEDS为空”的行,将其还原为缺失值,满足“暂时忽略”的要求

处理后示例结果

RANDID  BPMEDS  PERIOD
26   16799     0.0       1
27   16799     0.0       2
28   16799     0.0       3
29   19304     0.0       1
30   20375     0.0       1
31   20375     0.0       2
32   23727     1.0       1

内容的提问来源于stack exchange,提问作者swetach

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 19:36:32