合并Dataframe近乎重复行:过滤NA与较短字符串
解决Dataframe分组整合时剔除NA和短字符串的问题
我懂你现在的困扰:按指定字段(sel1、sel2)分组后,要对var1、var2这类字段做整合,既要丢掉NA值,还要保留较长的字符串——而且字符串里还有逗号、空格这些复杂结构,之前只搞定了NA过滤,短字符串的处理卡壳了对吧?
别担心,用pandas的分组聚合配合自定义函数就能完美解决这个问题,我给你一步步拆解:
1. 明确核心逻辑
针对每个sel1+sel2的唯一分组:
- 对var1、var2分别执行两步处理:
- 第一步:彻底过滤掉所有NA值
- 第二步:从剩下的非NA字符串里,保留长度最长的那个;如果有多个长度相同的最长字符串,还可以按需选择保留第一个或合并它们
2. 写一个通用的聚合处理函数
先搞一个专门处理单字段的函数,把NA过滤+长字符串保留的逻辑封装进去:
import pandas as pd import numpy as np def keep_longest_non_na(series): # 第一步:剔除该字段中的NA值 non_na_values = series.dropna() # 如果剔除后为空,返回NA if non_na_values.empty: return np.nan # 第二步:找到长度最长的字符串——str.len()会准确统计所有字符,包括逗号、空格 # idxmax()拿到最长字符串的索引,loc取出对应值 return non_na_values.loc[non_na_values.str.len().idxmax()]
这个函数完全不挑字符串结构,不管里面有多少特殊字符,长度计算都精准,完美适配你的复杂字符串场景。
3. 分组聚合实操
假设你的Dataframe叫df,直接用groupby配合上面的函数就能得到结果:
# 按sel1、sel2分组,对var1和var2应用自定义处理逻辑 aggregated_df = df.groupby(['sel1', 'sel2']).agg({ 'var1': keep_longest_non_na, 'var2': keep_longest_non_na }).reset_index()
4. 进阶:处理多个最长字符串的情况
如果同一个分组里有多个长度相同的最长字符串,你不想只保留第一个,而是想把它们合并起来,可以修改函数:
def keep_longest_or_merge(series): non_na_values = series.dropna() if non_na_values.empty: return np.nan # 找到最长字符串的长度阈值 max_length = non_na_values.str.len().max() # 筛选出所有符合最长长度的字符串 longest_strs = non_na_values[non_na_values.str.len() == max_length] # 去重后用逗号+空格合并(分隔符可以自己调整) return ', '.join(longest_strs.unique())
把这个函数替换到agg参数里就行。
5. 避坑提醒
如果你的字段是混合类型(比如既有字符串又有数字/NA),建议先转换成pandas的String类型,避免处理时出问题:
df['var1'] = df['var1'].astype('string') df['var2'] = df['var2'].astype('string')
这种类型会把NA保留为pd.NA,比普通的object类型处理起来更可靠。
内容的提问来源于stack exchange,提问作者Ferroao
相关产品推荐
相关产品推荐

