如何对Pandas DataFrame过滤并递归添加父层级数据?
解决方案:递归获取Pandas层级DataFrame的父层级行
1. 模拟层级结构数据
先构造符合你需求的示例DataFrame(替换成你的实际数据即可):
import pandas as pd data = { 'Level1': ['A', 'A', 'A', 'A', 'A', 'A'], 'Level2': [pd.NA, 'B', 'C', 'C', 'C', 'F'], 'Level3': [pd.NA, pd.NA, pd.NA, 'D', 'E', pd.NA], 'Status': ['N', 'N', 'N', 'E', 'V', 'V'] } df = pd.DataFrame(data)
2. 递归查找父层级的函数
定义函数来获取某一行的所有上层父层级索引:
def get_all_ancestors(row, df, level_cols): ancestors = [] current_row = row.copy() while True: # 提取当前行非空的Level列 non_nan_levels = current_row[level_cols].dropna() if len(non_nan_levels) <= 1: break # 已到最高父级,终止递归 # 生成父层级的筛选条件:保留前n-1个Level列的值,且剩余Level列为空 parent_levels = non_nan_levels[:-1] filter_cond = (df[parent_levels.index] == parent_levels.values).all(axis=1) # 确保右侧的Level列都为空,精准匹配父行 for col in level_cols[len(parent_levels):]: filter_cond &= df[col].isna() # 获取父行索引并加入列表 parent_idx = df[filter_cond].index[0] ancestors.append(parent_idx) current_row = df.loc[parent_idx] return ancestors
3. 筛选并收集目标行
执行筛选、递归收集父层级,最终生成结果:
# 提取所有Level列 level_cols = [col for col in df.columns if col.startswith('Level')] # 筛选Status为'E'或'V'的行 target_rows = df[df['Status'].isin(['E', 'V'])] # 收集需要保留的索引:目标行 + 所有父层级行 keep_indices = set(target_rows.index) for idx, row in target_rows.iterrows(): keep_indices.update(get_all_ancestors(row, df, level_cols)) # 按索引排序得到最终结果 result_df = df.loc[sorted(keep_indices)] print(result_df)
运行后输出的结果就是你需要的行0、2、3、4、5。
关键说明
- 父层级匹配逻辑:某一行的父级是去掉最右侧非空Level列后,剩余Level列值完全匹配且右侧Level列为空的行
- 递归终止条件:当行仅保留最高Level(Level1)时停止
- 最终结果自动去重并按原始索引排序,保证层级顺序清晰
内容的提问来源于stack exchange,提问作者Mth
相关产品推荐
相关产品推荐

