无循环实现月度关联Dataframe各列新增N/A占比统计
问题
我们有两个间隔1个月的CSV文件:FILE20221105.csv(上月数据)和FILE20221205.csv(本月数据),结构完全一致:Key(Int), Val1(String), Val2(String), Val3(String), Val4(String)。
需要基于Key做内连接后,对每个Val列计算**「上月该列非N/A、本月该列非N/A」的记录数占上月该列非N/A总记录数的比例**(注:原需求描述与示例存在偏差,示例实际统计的是该比例;若需统计「上月非N/A、本月为N/A」的比例,可直接修改条件),要求实现时禁止使用循环。
解决方案(Pandas实现)
以下是无需循环的向量式实现方案:
1. 读取并合并数据
先读取两个文件,保留原始的"N/A"字符串(不自动转为缺失值),然后基于Key做内连接,用后缀区分上月和本月的列:
import pandas as pd # 读取文件,禁用默认的缺失值解析,保留"N/A"为字符串 df_last = pd.read_csv("FILE20221105.csv", keep_default_na=False) df_current = pd.read_csv("FILE20221205.csv", keep_default_na=False) # 内连接,添加后缀区分上月/本月字段 merged = pd.merge(df_last, df_current, on="Key", suffixes=("_last", "_current"))
2. 批量计算统计值
提取所有Val列名,然后用布尔矩阵批量处理所有列:
# 获取所有Val列的名称 val_cols = [col for col in df_last.columns if col.startswith("Val")] # 生成两个布尔矩阵: # 1. 上月该列非N/A的记录 last_valid = merged[[f"{col}_last" for col in val_cols]] != "N/A" # 2. 上月非N/A且本月非N/A的记录(对应示例需求) both_valid = last_valid & (merged[[f"{col}_current" for col in val_cols]] != "N/A") # 计算分母(上月非N/A总记录数)和分子(上月非N/A且本月非N/A的记录数) denominators = last_valid.sum() numerators = both_valid.sum() # 整理成指定输出格式 result = {col: f"{num}/{den}" for col, num, den in zip(val_cols, numerators, denominators)}
3. 输出结果
遍历输出:
for col, ratio in result.items(): print(f"{col}:{ratio}")
示例输出
运行上述代码后,会得到与示例一致的结果:
Val1:5/7 Val2:3/6 Val3:6/7 Val4:4/6
结果说明
- Val1:上月非N/A共7条,其中本月保持非N/A的有5条,比例5/7
- Val2:上月非N/A共6条,本月保持非N/A的有3条,比例3/6
- Val3:上月非N/A共7条,本月保持非N/A的有6条,比例6/7
- Val4:上月非N/A共6条,本月保持非N/A的有4条,比例4/6
内容的提问来源于stack exchange,提问作者Sunil Shukla
相关产品推荐
相关产品推荐

