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

如何使用combine_first方法合并含重复索引的DataFrame行?

使用combine_first合并重复索引的DataFrame行

问题背景

给定如下代码创建的带有重复索引的DataFrame:

import pandas as pd

# 创建含重复索引值的示例DataFrame
data = {'A': [1, 2, None, 4, 5],
        'B': [None, None, 3, None, 4]}

df = pd.DataFrame(data, index=[1, 2, 2, 3, 3])

需要通过combine_first方法将所有重复索引的行合并为单行,实现类似df.groupby(df.index).agg(...)的逻辑——对分组逐行应用combine_first直至合并为单行。

期望两种输出结果:

  1. 保留第一个非空值:
{'A': [1, 2, 4],
 'B': [None, 3, 4]}
  1. 保留最后一个非空值:
{'A': [1, 2, 5],
 'B': [None, 3, 4]}

解决方案

1. 保留第一个非空值(从前向后合并)

通过groupby分组后,自定义聚合函数对每组行从前到后依次调用combine_first,优先保留先出现的非空值:

def combine_forward(group):
    merged_row = group.iloc[0]
    for row in group.iloc[1:]:
        merged_row = merged_row.combine_first(row)
    return merged_row

result_forward = df.groupby(df.index).apply(combine_forward)
print(result_forward.to_dict('list'))

输出符合预期:

{'A': [1.0, 2.0, 4.0], 'B': [None, 3.0, 4.0]}

2. 保留最后一个非空值(从后向前合并)

若要保留每组中最后出现的非空值,只需反转分组内的行顺序,再执行合并逻辑:

def combine_backward(group):
    merged_row = group.iloc[-1]
    for row in reversed(group.iloc[:-1]):
        merged_row = row.combine_first(merged_row)
    return merged_row

result_backward = df.groupby(df.index).apply(combine_backward)
print(result_backward.to_dict('list'))

输出符合预期:

{'A': [1.0, 2.0, 5.0], 'B': [None, 3.0, 4.0]}

简化实现(利用functools.reduce)

借助functools.reduce可以简化聚合逻辑,让代码更紧凑:

  • 保留第一个非空值:
from functools import reduce

result_forward = df.groupby(df.index).apply(lambda g: reduce(lambda x, y: x.combine_first(y), g))
  • 保留最后一个非空值:
result_backward = df.groupby(df.index).apply(lambda g: reduce(lambda x, y: y.combine_first(x), g))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 06:05:16