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

如何优雅计算同结构DataFrame各列匹配百分比(忽略NaN)

优雅实现DataFrame列匹配百分比计算

核心思路

用Pandas的向量化操作替代循环与apply,直接对整列做批量计算,既提升效率又简化逻辑。核心是先过滤真值数据集(df2)的NaN值,再计算匹配数与有效样本数的比值。

优化后的代码实现

import pandas as pd

# 读取数据,保留原始类型(不转成str,避免把NaN变成字符串'nan')
test_set = pd.read_excel(file_path)
a_set = pd.read_excel(file2_path)

# 按file_name合并两个数据集(保持与原逻辑一致的inner join)
merged_df = a_set.merge(test_set, on='file_name', suffixes=('_x', '_y'))

# 提取需要对比的字段(排除file_name)
fields = [col for col in test_set.columns if col != 'file_name']

# 1. 计算真值数据集(_y列)每列的非NaN有效样本数
valid_counts = merged_df[[f"{field}_y" for field in fields]].notna().sum()

# 2. 计算每列的匹配数:仅当真值非NaN时,对比两列小写后是否相等
match_mask = (merged_df[[f"{field}_x" for field in fields]].apply(lambda col: col.str.lower()) 
              == merged_df[[f"{field}_y" for field in fields]].apply(lambda col: col.str.lower()))
# 把真值为NaN的位置设为False(不参与计数)
match_mask = match_mask.where(merged_df[[f"{field}_y" for field in fields]].notna(), False)
matches = match_mask.sum()

# 3. 计算匹配百分比,保留两位小数
match_percentages = (matches / valid_counts * 100).round(2)

# 重置索引为原字段名
match_percentages.index = fields

print(match_percentages)

代码说明

  • 避免无效类型转换:不再将DataFrame强制转为str,保留原始NaN,用notna()更精准判断空值。
  • 向量化提升效率:用整列对比替代逐行apply,处理大数据集时速度优势明显。
  • 逻辑拆分清晰:分步骤计算有效样本数、匹配数、百分比,代码可读性更强。
  • 结果直观对齐:将结果索引重置为原字段名,输出格式更符合需求。

示例验证

针对你给出的示例:

  • 合并后country_name_y的有效样本数为3,匹配数为2。
  • 计算得2/3*100≈66.67%,与预期完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 22:35:37