如何实现自动向if语句叠加逻辑测试的循环,用于数据集相关性分析
Pandas自动迭代叠加最优逻辑匹配度测试方案
核心实现思路
每轮迭代会先基于上一轮保留的最优逻辑过滤数据集,再遍历所有未使用过的变量+运算符组合生成新的判断条件,计算每个新条件叠加后的percent_match和percent_no_match,筛选出当前轮次效果最优的条件叠加到总逻辑中,直到触发终止条件为止。
核心代码实现
依赖导入与基础配置
import pandas as pd import itertools # 基础配置,替换为实际业务参数 INPUT_COLS = ["var1", "var2", "var3", "var4"] # 输入变量列名 TARGET_COL = "target" # 输出标签列名 OPERATORS = [">", ">=", "<=", "<"] # 支持的比较运算符 # 迭代终止条件 STOP_MATCH_THRESHOLD = 95 # 匹配度达标阈值 STOP_NO_MATCH_THRESHOLD = 1 # 不匹配度达标阈值 MAX_ITER = 5 # 最多迭代轮数,避免无限循环
核心工具函数
def calc_match_metrics(df: pd.DataFrame, logic_mask: pd.Series, target_value=1) -> tuple[float, float]: """ 输入数据集和逻辑判断掩码,计算匹配度与不匹配度 target_value可根据实际输出标签调整 """ filtered = df[logic_mask] total_in_logic = len(filtered) if total_in_logic == 0: return 0.0, 100.0 # 空匹配直接判定为无效逻辑 match_cnt = len(filtered[filtered[TARGET_COL] == target_value]) no_match_cnt = total_in_logic - match_cnt percent_match = (match_cnt / total_in_logic) * 100 percent_no_match = (no_match_cnt / total_in_logic) * 100 return round(percent_match, 2), round(percent_no_match, 2) def gen_single_condition_mask(df: pd.DataFrame, col: str, op: str, threshold) -> pd.Series: """根据变量、运算符、阈值生成单条件逻辑掩码""" if op == ">": return df[col] > threshold elif op == ">=": return df[col] >= threshold elif op == "<=": return df[col] <= threshold elif op == "<": return df[col] < threshold else: raise ValueError(f"不支持的运算符: {op}")
自动迭代主逻辑
if __name__ == "__main__": # 替换为实际数据集 df = pd.read_csv("your_data.csv") # 初始化总逻辑掩码,初始为全True(无过滤条件) total_logic_mask = pd.Series([True]*len(df), index=df.index) used_conditions = [] # 记录已使用的条件避免重复 current_best_match = 0.0 current_best_no_match = 100.0 for iter_round in range(1, MAX_ITER+1): print(f"\n===== 第{iter_round}轮迭代 =====") round_candidates = [] # 遍历所有未使用的变量+运算符+阈值组合 for col in [c for c in INPUT_COLS if c not in [cond[0] for cond in used_conditions]]: # 阈值可替换为分箱结果减少遍历量 unique_vals = sorted(df[col].unique()) for op in OPERATORS: for threshold in unique_vals: # 生成新条件并叠加现有逻辑 new_cond_mask = gen_single_condition_mask(df, col, op, threshold) combined_mask = total_logic_mask & new_cond_mask # 计算评估指标 match_pct, no_match_pct = calc_match_metrics(df, combined_mask) round_candidates.append({ "match_pct": match_pct, "no_match_pct": no_match_pct, "col": col, "op": op, "threshold": threshold, "mask": new_cond_mask }) if not round_candidates: print("无可用新条件,迭代终止") break # 筛选当前轮最优条件:优先匹配度最高,其次不匹配度最低 round_candidates.sort(key=lambda x: (-x["match_pct"], x["no_match_pct"])) best_cond = round_candidates[0] # 无指标提升则终止迭代 if best_cond["match_pct"] <= current_best_match and best_cond["no_match_pct"] >= current_best_no_match: print("指标无提升,迭代终止") break # 更新总逻辑与指标 total_logic_mask &= best_cond["mask"] current_best_match = best_cond["match_pct"] current_best_no_match = best_cond["no_match_pct"] used_conditions.append((best_cond["col"], best_cond["op"], best_cond["threshold"])) # 打印本轮结果 print(f"本轮最优条件:{best_cond['col']} {best_cond['op']} {best_cond['threshold']}") print(f"当前总匹配度:{current_best_match}%,总不匹配度:{current_best_no_match}%") print(f"已叠加所有条件:{[' '.join(map(str, cond)) for cond in used_conditions]}") # 达到终止阈值则退出 if current_best_match >= STOP_MATCH_THRESHOLD or current_best_no_match <= STOP_NO_MATCH_THRESHOLD: print("达到终止指标,迭代结束") break
可调整优化点
- 阈值生成逻辑:当前用变量唯一值遍历,可替换为等频分箱、等距分箱结果,减少遍历次数提升运行效率
- 条件筛选规则:可根据业务需求调整候选条件排序权重,比如优先降低不匹配度,可修改
sort方法的排序key - 重复变量限制:当前默认同一变量只能使用一次,如有多区间判断需求可去掉该限制
内容的提问来源于stack exchange,提问作者josseossa
相关产品推荐
相关产品推荐

