基于重复ID条件更新DataFrame行状态的实现方法咨询
基于重复ID条件更新DataFrame行状态的实现方法咨询
嗨,Julie!我完全明白你的需求啦——你需要给每一行occurrence=10的数据,匹配对应id下occurrence=1行的status值,对吧?咱们来一步步解决这个问题,先梳理下你现有尝试的问题,再给出几种实用的解决方案。
首先说下你之前的尝试:用df[df['id'].duplicated(keep=False)]确实能筛选出所有存在重复id的行,但还没精准定位到occurrence=1的状态值;而你用groupby.transform的写法出问题,是因为lambda里的update不会返回有效数据,才导致结果全是None。
下面给你三种可行的实现方法:
方法一:用Merge关联映射状态
这种方法逻辑直观,先提取出occurrence=1的行作为状态映射表,再和原表关联匹配:
# 提取occurrence=1的id与对应status的映射表 status_mapping = df[df['occurrence'] == 1][['id', 'status']] # 左连接原表,将对应id的status值带过来 df = df.merge(status_mapping, on='id', suffixes=('', '_from_occ1'), how='left') # 给occurrence=10的行赋值status df.loc[df['occurrence'] == 10, 'status'] = df.loc[df['occurrence'] == 10, 'status_from_occ1'] # 清理临时生成的列 df = df.drop('status_from_occ1', axis=1)
方法二:利用GroupBy+向前填充(最简洁)
你提到occurrence=10的行总是在occurrence=1的行之后,这个特性刚好可以用**向前填充(ffill)**来简化操作:
# 按id分组,对每个组内的status列向前填充 df['status'] = df.groupby('id')['status'].ffill()
这个写法直接利用行顺序的特性,每个occurrence=10的行会自动继承同组内前面occurrence=1行的status值,代码非常简洁高效。如果担心存在只有occurrence=10没有1的id,可以加上fillna()保留原空值:
df['status'] = df.groupby('id')['status'].ffill().fillna(df['status'])
方法三:用字典映射+Map赋值
先构建id到status的字典,再通过map函数给目标行赋值:
# 构建id对应status的字典(仅取occurrence=1的行) id_to_status = df[df['occurrence'] == 1].set_index('id')['status'].to_dict() # 给occurrence=10的行的status赋值 df.loc[df['occurrence'] == 10, 'status'] = df.loc[df['occurrence'] == 10, 'id'].map(id_to_status)
这三种方法都能满足你的需求,其中方法二因为利用了你给出的行顺序特性,是最省心的选择~
备注:内容来源于stack exchange,提问作者Julie Agopian
相关产品推荐
相关产品推荐

