Pandas:按ID合并DataFrame行并清理NaN无效数据
解决按ID分组合并重复行、保留有效数据的问题
这是数据清理里很常见的场景,用Pandas就能快速实现你的需求。先明确你的输入和目标:
原始DataFrame:
id data data2 0 12 NaN 50.0 1 12 a 50.0 2 12 a NaN 3 52 b NaN 4 52 NaN 20.0 5 52 NaN 20.0
期望输出:
id data data2 0 12 a 50 1 52 b 20
解决方案
这里提供两种实用的方法,你可以根据自己的场景选择:
方法一:自定义聚合函数(灵活通用)
通过groupby分组后,用自定义函数提取每个组里第一个非NaN的有效数据:
import pandas as pd import numpy as np # 构造你的原始数据 df = pd.DataFrame({ 'id': [12,12,12,52,52,52], 'data': [np.nan, 'a', 'a', 'b', np.nan, np.nan], 'data2': [50.0,50.0,np.nan,np.nan,20.0,20.0] }) # 定义聚合逻辑:取列中第一个非空值 def get_first_valid(series): valid_vals = series.dropna() return valid_vals.iloc[0] if not valid_vals.empty else np.nan # 按id分组聚合,然后重置索引 cleaned_df = df.groupby('id').agg(get_first_valid).reset_index() # 可选:将data2的浮点型转为整型(匹配你的期望输出格式) cleaned_df['data2'] = cleaned_df['data2'].astype(int) print(cleaned_df)
方法二:排序+first()(简洁高效)
利用排序把非NaN值提前,再分组取第一个值,代码更简洁:
import pandas as pd import numpy as np df = pd.DataFrame({ 'id': [12,12,12,52,52,52], 'data': [np.nan, 'a', 'a', 'b', np.nan, np.nan], 'data2': [50.0,50.0,np.nan,np.nan,20.0,20.0] }) # 对每列排序,让非空值排在前面 sorted_df = df.apply(lambda col: col.sort_values(na_position='last')) # 分组后取每组第一个值 cleaned_df = sorted_df.groupby('id').first().reset_index() # 转换data2类型 cleaned_df['data2'] = cleaned_df['data2'].astype(int) print(cleaned_df)
两种方法都能得到你想要的结果,方法一适合后续可能有更复杂聚合逻辑的场景,方法二更适合当前这种每列仅需保留唯一有效值的情况。
内容的提问来源于stack exchange,提问作者velxundussa
相关产品推荐
相关产品推荐

