Python pandas如何按条件筛选信息完整度最高的行
Pandas按ID分组筛选信息完整度最高行的解决方案
推荐方案(比计算字符长度更贴合完整度需求)
核心逻辑优先以「非缺失字段的数量」作为完整度判断标准,避免单个长文本字段拉高总长度但实际大量字段缺失的问题,同数量下可叠加字符串总长度作为第二判断维度,同时可以直接保留原索引。
具体实现步骤
- 统一缺失值标准:把空字符串、自定义的
N/A都替换为pandas可识别的标准缺失值pd.NA - 计算完整度得分:优先统计每行的非缺失字段数,可选叠加所有字段的字符串总长度作为次级判断条件
- 分组取最优行:通过
idxmax()直接获取每个ID分组下得分最高行的原索引,再从原表筛选对应行即可
完整可运行代码
import pandas as pd # 构造示例数据 data = { 'ID': ['ABD12567']*5, 'Title': ['Title1']*5, 'Category': ['', 'N/A', 'Category1', '', 'N/A'], 'Company': ['Company1', '', 'Company1', 'Company1', 'Company1'], 'Field': ['', 'Field1', 'Field1', '', 'Field1'] } df = pd.DataFrame(data) # 步骤1:统一替换自定义缺失值为标准缺失值 df.replace(['', 'N/A'], pd.NA, inplace=True) # 步骤2:计算完整度指标 # 第一优先级:非缺失字段数量 df['non_null_cnt'] = df.notna().sum(axis=1) # 可选第二优先级:所有字段总字符串长度,同非缺失数下内容越丰富得分越高 df['total_str_len'] = df.fillna('').astype(str).apply(lambda x: x.str.len()).sum(axis=1) # 步骤3:筛选每个ID的最优行 # 仅用非缺失数判断的写法 max_idx = df.groupby('ID')['non_null_cnt'].idxmax() # 需叠加第二优先级的写法:先排序再取每组第一个 # df = df.sort_values(['ID', 'non_null_cnt', 'total_str_len'], ascending=[True, False, False]) # max_idx = df.groupby('ID').head(1).index # 从原表提取结果,删除辅助计算列 result = df.loc[max_idx].drop(columns=['non_null_cnt', 'total_str_len']) print(result)
原有思路的修正方案
你之前计算combined_len的思路也可以用,问题出在使用agg取最大值时没有保留原索引,改为用idxmax()获取最大值对应的原索引即可,修改后代码如下:
# 你的原逻辑新增combined_len列后,直接取每个ID分组下combined_len最大值的索引 max_idx = catalog_1.groupby('ID')['combined_len'].idxmax() # 直接从原表筛选对应行即可 catalog_11 = catalog_1.loc[max_idx]
内容的提问来源于stack exchange,提问作者XSCD
相关产品推荐
相关产品推荐

