import pandas as pd
import re
def filter_param_dataframe_row_based(df_diff_cleaned):
"""
基于「单行内部」统计进行筛选,保留满足条件的行(每行独立计算,不依赖全局数据)
筛选条件:
1. 该行内每个解析出的step(如ME),在当前行的出现频次≥10次
2. 该行内每个step对应的非0元素占比<10%(0.1)
参数:
df_diff_cleaned (pd.DataFrame):包含'param'字段的输入DataFrame,
param字段的值为列表,列表元素格式为"step#param:value"
返回:
pd.DataFrame:满足所有筛选条件的结果DataFrame,索引已重置
"""
# --------------- 内部辅助函数:解析单个param元素 ---------------
def parse_param_element(element):
"""解析单个param字符串,返回(step, 数值),解析失败返回(None, None)"""
pattern = r'^([^#]+)#[^:]+:([-+]?\d+\.\d+)$'
match = re.match(pattern, element)
if match:
step = match.group(1).strip()
value = float(match.group(2))
return (step, value)
else:
return (None, None)
# --------------- 步骤1:定义单行筛选逻辑(核心:单行内独立统计) ---------------
def filter_single_row(param_list):
"""
判断单行是否满足条件(基于该行内部数据统计)
"""
# 步骤1.1:提取当前行的step和对应数值,构建映射关系
row_step_info = {} # 字典结构:key=step,value=[该step在该行的所有数值列表]
for element in param_list:
step, value = parse_param_element(element)
if step is not None and value is not None:
if step not in row_step_info:
row_step_info[step] = []
row_step_info[step].append(value)
# 若当前行无有效step数据,直接返回False
if not row_step_info:
return False
# 步骤1.2:逐一验证该行的每个step是否满足两个核心条件
for step, values in row_step_info.items():
# 条件1:该step在当前行的出现频次≥10次(values列表长度即为该行频次)
row_step_count = len(values)
if row_step_count < 10:
return False
# 条件2:该step在当前行的非0元素占比<10%(0.1)
# 考虑浮点精度,避免微小数值(如1e-9)被误判为非0
non_zero_count = sum(1 for v in values if abs(v) > 1e-8)
non_zero_ratio = non_zero_count / row_step_count # 单行内非0占比
if non_zero_ratio >= 0.1:
return False
# 所有step均满足两个条件,返回True
return True
# --------------- 步骤2:执行单行筛选,得到结果 ---------------
df_result = df_diff_cleaned[
df_diff_cleaned['param'].apply(filter_single_row)
].reset_index(drop=True)
return df_result