Pandas中合并并补全相同ID的行
解决Pandas合并同ID行并补全缺失值的问题
刚接触Pandas遇到这种需求很正常,drop_duplicates确实帮不上忙——它的核心是移除重复行,而不是合并行并补全缺失值。针对你的场景,我们可以用分组+填充/提取的思路来实现,下面是具体的解决方案:
方法1:分组后双向填充取首行
因为你的数据已经按ID排序过,分组后我们可以对每个ID组先向下填充(bfill)再向上填充(ffill),这样组内所有行都会变成补全后的完整行,最后取每组的第一行即可:
import pandas as pd import numpy as np # 构造你的测试数据 data = { 'ID': [200, 201, 211, 211, 211, 213, 216, 216, 217], 'LU': ['B', 'C', 'A', np.nan, np.nan, 'A', 'K', np.nan, 'B'], 'MA': ['B', 'C', np.nan, 'D', np.nan, 'A', 'K', np.nan, 'B'], 'ME': ['B', 'C', np.nan, 'D', np.nan, np.nan, 'K', np.nan, 'B'], 'JE': [np.nan, 'C', np.nan, 'D', np.nan, np.nan, 'K', np.nan, 'B'], 'VE': [np.nan, 'C', np.nan, np.nan, np.nan, np.nan, 'K', np.nan, 'B'], 'SA': [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan], 'DI': [np.nan, np.nan, np.nan, np.nan, 'B', np.nan, np.nan, 'K', np.nan] } df = pd.DataFrame(data) # 核心代码 result = df.groupby('ID').apply(lambda group: group.bfill().ffill().head(1)).reset_index(drop=True) print(result)
运行后会得到你期望的结果:
ID LU MA ME JE VE SA DI 0 200 B B B NaN NaN NaN NaN 1 201 C C C C C NaN NaN 2 211 A D D D NaN NaN B 3 213 A A NaN NaN NaN NaN NaN 4 216 K K K K K NaN K 5 217 B B B B B NaN NaN
原理说明
bfill():把当前行下方的非缺失值向上填充,比如ID211的第一行缺失的MA/ME/JE列,会被第二行的D填充;ffill():把当前行上方的非缺失值向下填充,确保所有缺失位置都被补全;- 最后取每组第一行,因为组内所有行已经完全一致了。
方法2:分组后提取每列的非缺失值
如果能保证同一ID下的同一列只有一个非缺失值(你的场景符合这个情况),可以直接对每个列提取组内的非缺失值:
result = df.groupby('ID').agg(lambda x: x.dropna().iloc[0] if not x.dropna().empty else np.nan) print(result.reset_index())
这个方法更直接,针对每个列,我们只保留组内第一个非缺失值(如果有的话),否则留空。
这两种方法都能完美解决你的需求,第一种更通用,即使同一列存在多个非缺失值也能处理(会按填充逻辑保留对应值),第二种则更高效,适合你的特定场景。
内容的提问来源于stack exchange,提问作者bptste
相关产品推荐
相关产品推荐

