如何递归遍历Pandas DataFrame并按规则计算布尔结果?
问题描述
现有如下Pandas DataFrame:
id parent_id result 1 0 True 2 0 False 3 1 True 4 1 False 5 2 True 6 2 False 7 4 True 8 4 True
需要递归遍历整个DataFrame,计算规则为:若节点存在子节点,先对所有子节点的result值执行OR运算,再将该中间结果与父节点的result值执行AND运算,即遵循逻辑:AND(parent['result'], OR(descendants['result']))。最终需要计算如下布尔表达式的结果:
df.loc[df['id'] == 1, 'result'] AND (df.loc[df['id'] == 3, 'result'] OR ( df.loc[df['id'] == 4, 'result'] AND ( df.loc[df['id'] == 7, 'result'] OR df.loc[df['id'] == 8, 'result'] ) ) ) OR ( df.loc[df['id'] == 2, 'result'] AND ( df.loc[df['id'] == 5, 'result'] OR df.loc[df['id'] == 6, 'result'] ) )
解决方案
步骤1:构建父子节点映射结构
先把DataFrame转换成父节点到子节点的映射字典,方便快速定位子节点:
import pandas as pd # 初始化目标DataFrame df = pd.DataFrame({ 'id': [1,2,3,4,5,6,7,8], 'parent_id': [0,0,1,1,2,2,4,4], 'result': [True, False, True, False, True, False, True, True] }) # 生成父节点到子节点ID的映射 parent_to_children = df.groupby('parent_id')['id'].apply(list).to_dict()
步骤2:编写递归计算函数
定义递归函数,输入节点ID,返回该节点按规则计算后的布尔结果:
def calculate_node(node_id): # 获取当前节点的result值 node_result = df.loc[df['id'] == node_id, 'result'].iloc[0] # 获取当前节点的所有子节点 children = parent_to_children.get(node_id, []) if not children: # 无子女节点,直接返回自身result值 return node_result else: # 递归计算所有子节点的结果,再执行OR运算 children_results = [calculate_node(child_id) for child_id in children] or_result = any(children_results) # 父节点result与子节点OR结果执行AND运算 return node_result and or_result
步骤3:计算最终结果
根节点是parent_id=0的所有节点,对这些节点的计算结果执行OR运算得到最终值:
# 获取所有根节点 root_nodes = parent_to_children.get(0, []) # 计算每个根节点的结果,再执行OR运算 final_result = any(calculate_node(node) for node in root_nodes) print(final_result) # 输出:True
手动验证结果
- 节点7、8:无子女,结果分别为
True、True,OR运算后为True - 节点4:自身
result为False,与子节点OR结果True做AND,得到False - 节点3:无子女,结果为
True - 节点1:自身
result为True,与子节点3(True)和4(False)的OR结果True做AND,得到True - 节点5、6:无子女,结果分别为
True、False,OR运算后为True - 节点2:自身
result为False,与子节点OR结果True做AND,得到False - 最终根节点1(
True)和2(False)做OR,结果为True,与代码输出一致
内容的提问来源于stack exchange,提问作者harp1814
相关产品推荐
相关产品推荐

