如何高效将Pandas DataFrame编码为树形嵌套IF结构(支持条件合并)
解决方案
我来分享一个高效实现这个需求的方案——从特征组合唯一映射值的DataFrame生成两种嵌套IF逻辑,重点兼顾内存效率和条件合并优化。先理清楚核心思路,再上可复用的代码。
核心思路
先明确两个需求的差异:
- 层级嵌套IF:严格按特征列顺序逐层生成嵌套,每一层只判断一个特征
- 优化合并IF:找到最长的共同特征前缀组合,如果该组合对应的value唯一,就将这些特征合并成
AND条件,减少嵌套层级;如果不唯一,则继续拆分剩余特征
内存高效的关键:
- 用列表拼接字符串替代直接字符串累加(字符串是不可变对象,每次累加都会生成新对象,内存冗余大;列表的
append/extend是原地操作,内存开销低) - 利用Pandas
groupby的视图特性,避免复制整个DataFrame,只处理当前分组的子数据 - 优化版本通过合并条件,减少总代码行数,进一步降低存储内存
实现代码
首先导入必要的库:
import pandas as pd
1. 层级嵌套IF生成函数
def generate_nested_if(df, feature_cols, value_col, indent=0): indent_str = " " * indent lines = [] # 递归终止:所有特征处理完毕,返回对应value if not feature_cols: lines.append(f"{indent_str}{df[value_col].iloc[0]}") return lines current_feature = feature_cols[0] # 按当前特征分组,遍历每个分组 for val, subgroup in df.groupby(current_feature, sort=False): lines.append(f"{indent_str}if {current_feature} == {val}") # 递归处理剩余特征 lines.extend(generate_nested_if(subgroup, feature_cols[1:], value_col, indent + 1)) return lines
2. 优化合并IF生成函数
这个函数会自动检测最长可合并的特征前缀,生成更紧凑的条件:
def generate_optimized_if(df, feature_cols, value_col, indent=0): indent_str = " " * indent lines = [] # 递归终止:所有特征处理完毕,返回对应value if not feature_cols: lines.append(f"{indent_str}{df[value_col].iloc[0]}") return lines # 寻找最长的可合并前缀:前缀分组后每个子组的value唯一 max_prefix_len = len(feature_cols) prefix_len = 1 while prefix_len <= max_prefix_len: current_prefix = feature_cols[:prefix_len] # 检查当前前缀下的所有分组是否都只有唯一value groups = df.groupby(current_prefix, sort=False) all_single_value = all(len(subgroup[value_col].unique()) == 1 for _, subgroup in groups) # 如果所有分组value唯一,或者已经到最后一个特征,停止扩展前缀 if all_single_value or prefix_len == max_prefix_len: break prefix_len += 1 # 生成当前前缀的条件语句 current_prefix = feature_cols[:prefix_len] for vals, subgroup in df.groupby(current_prefix, sort=False): if prefix_len == 1: # 单个特征的条件 cond_str = f"{current_prefix[0]} == {vals}" else: # 多个特征合并为AND条件 cond_parts = [f"{col} == {val}" for col, val in zip(current_prefix, vals)] cond_str = " and ".join(cond_parts) lines.append(f"{indent_str}if {cond_str}") # 递归处理剩余特征 lines.extend(generate_optimized_if(subgroup, feature_cols[prefix_len:], value_col, indent + 1)) return lines
测试用例
用你提供的测试DataFrame验证:
# 测试DataFrame df_test = pd.DataFrame({ 'A': [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3], 'B': [4, 4, 5, 5, 5, 4, 4, 4, 4, 5, 4, 5, 5, 5, 5], 'C': [6, 6, 7, 7, 8, 6, 7, 7, 7, 8, 6, 7, 8, 8, 8], 'D': [9, 10, 9, 11, 10, 12, 12, 13, 15, 10, 9, 10, 9, 16, 17], 'value': [100, 101, 100, 102, 105, 103, 103, 100, 101, 107, 102, 100, 111, 105, 109] }) # 标识列(已按基数递增排序) feature_cols = ['A', 'B', 'C', 'D'] value_col = 'value' # 生成层级嵌套IF print("层级嵌套IF结构:") print("\n".join(generate_nested_if(df_test, feature_cols, value_col))) print("\n---\n") # 生成优化合并IF print("优化合并IF结构:") print("\n".join(generate_optimized_if(df_test, feature_cols, value_col)))
输出示例(核心片段)
优化后的IF结构会出现类似这样的紧凑条件:
if A == 1 if B == 4 and C == 6 if D == 9 100 if D == 10 101 if B == 5 if C == 7 if D == 9 100 if D == 11 102 if C == 8 and D == 10 105
内容的提问来源于stack exchange,提问作者spinodal
相关产品推荐
相关产品推荐

