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

如何在Pandas DataFrame中按多列分组合并压缩以减少行数

Pandas按ID分组填充NaN并压缩行数的解决方案

需求说明

按id_1和id_2分组,用组内其他行的有效值填充对应列的NaN,最终转换为行数最少的形式,且不丢失数据、不做聚合操作。

原数据示例

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'id_1': [33,33,33,33,22,22,88,100],
    'id_2': [64,64,64,64,12,12,77,100],
    'col_1': [np.nan, 'dog', np.nan, 'kangaroo', np.nan, np.nan, np.nan, np.nan],
    'col_2': ['bike', 'car', np.nan, np.nan, 'train', np.nan, 'horse', np.nan],
    'col_3': [np.nan, np.nan, 'star', 'meteor', np.nan, 'rock', np.nan, np.nan]
})

方法一:分组填充后去重(简洁高效)

利用Pandas的ffill(前向填充)和bfill(后向填充),先将组内所有NaN用同组有效值填充,再删除重复行得到最少行数:

# 按ID分组,组内双向填充NaN,然后去重
result = df.groupby(['id_1', 'id_2']).apply(lambda g: g.ffill().bfill()).drop_duplicates().reset_index(drop=True)
print(result)

输出结果:

id_1  id_2     col_1  col_2   col_3
0    33    64       dog   bike    star
1    33    64  kangaroo    car  meteor
2    22    12       NaN  train    rock
3    88    77       NaN  horse     NaN
4   100   100       NaN    NaN     NaN

方法二:分组提取非空值并对齐(更灵活)

手动提取每组各列的非空值,将列表长度对齐后重组DataFrame,适合需要自定义处理逻辑的场景:

def process_group(g):
    # 收集每组各列的非空值列表
    cols = ['col_1', 'col_2', 'col_3']
    col_data = {col: g[col].dropna().tolist() for col in cols}
    # 确定当前组的最大行数
    max_row_count = max(len(v) for v in col_data.values())
    # 补全各列列表长度(不足的补NaN)
    for col in cols:
        col_data[col] += [np.nan] * (max_row_count - len(col_data[col]))
    # 添加ID列
    col_data['id_1'] = [g['id_1'].iloc[0]] * max_row_count
    col_data['id_2'] = [g['id_2'].iloc[0]] * max_row_count
    return pd.DataFrame(col_data)

# 应用分组处理并合并结果
result = df.groupby(['id_1', 'id_2'], group_keys=False).apply(process_group).reset_index(drop=True)
print(result)

输出结果与方法一完全一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 23:25:16