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

不修改行序,按指定列合并行并保留各列首个非空值

解决DataFrame按identity合并并保留首个非空值且不改变行序的问题

需求说明

  • 禁止修改或排序行序列(此前使用groupby按id分组会改变/排序行序)
  • 所有DataFrame均包含参考列identity,需按数据重要性顺序拼接(重要性高的在前)
  • 合并相同identity值的行:合并后每行的各列需取该组内首个非空值(涵盖numpy.nan、空字符串、CSV导入的无值情况),若所有行均无值则列留空

基础代码

import pandas as pd
import numpy as np

new_df_one = pd.DataFrame({
    'identity':['1234','9999','1111'],
    'column_a':['hhhh','aaaa',''],
    'column_b':['hhhh',np.nan,np.nan],
    'column_c':[np.nan,'aaaa',''],
    'column_d':['hhhh','aaaa','']
})

new_df_two = pd.DataFrame({
    'identity':['1234','9999'],
    'column_a':[np.nan,np.nan],
    'column_b':[np.nan,np.nan],
    'column_c':[np.nan,np.nan],
    'column_d':['zzzz',np.nan]
})

original_df = pd.DataFrame({
    'identity':['1234','1111'],
    'column_a':[np.nan,'gggg'],
    'column_b':[np.nan,'gggg'],
    'column_c':['hhhh','gggg'],
    'column_d':['hhhh','gggg']
})

concat_df = pd.concat([new_df_one, new_df_two, original_df], ignore_index=True)

此前尝试的问题

  • Test 1:使用agg(lambda x: ''.join(x))会将所有值拼接,不符合"取首个非空值"的要求
  • Test 2:groupby('id').first()存在两个问题:一是groupby默认会对分组键排序,破坏原行序;二是first()会直接取组内第一行的值,不会跳过空字符串/NaN去取后面的有效值

解决方案

  1. 统一空值表示:将空字符串转换为np.nan,确保所有无值情况可以被统一处理
  2. 按identity分组时设置sort=False,保留原数据中identity首次出现的顺序
  3. 自定义聚合函数,取每组内首个非空值;若全为空则留空
# 统一空值:将空字符串转为np.nan
concat_df = concat_df.replace('', np.nan)

# 按identity分组(不排序),取每组首个非空值
result_df = concat_df.groupby('identity', sort=False).agg(
    lambda x: x.dropna().iloc[0] if not x.dropna().empty else np.nan
).reset_index()

# 可选:将np.nan转回空字符串,匹配预期结果的显示格式
result_df = result_df.replace(np.nan, '')

print(result_df)

运行结果

identity column_a column_b column_c column_d
0     1234     hhhh     hhhh     hhhh     hhhh
1     9999     aaaa              aaaa     aaaa
2     1111     gggg     gggg     gggg     gggg

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 12:07:08