如何编写Python函数对DataFrame数量列执行多规则校验
报错根因
原代码报错是因为qty_col = [col for col in df.columns if 'qty' in col]得到的是列名字符串组成的列表,不是pandas的Series/DataFrame结构,不存在isnull()方法;且原逻辑仅做了空值判断,没有覆盖约定的取值规则,无法满足校验需求。
校验规则落地逻辑
先把规则转化为可代码判断的分支:
- 单张表qty列数量≥2时,
"-"判定为合法值;单qty列表该值判定为非法 - 固定合法枚举值:
"AR" - 格式合法的数值类值:整数/浮点数,可在末尾带任意字母单位(含要求的
EA、FT、KG等,单位和数值之间允许有空格) - 空值、不符合上述格式的其他值均判定为非法
- 逐行校验时,只要该行任意一个qty列取值非法,就返回该行对应的
line no;所有qty列取值均合法则返回True
可直接复用的实现代码
import pandas as pd import numpy as np import re def validate_qty_columns(df: pd.DataFrame): # 提取所有名称含qty的列 qty_cols = [col for col in df.columns if 'qty' in col] # 多qty列场景下允许"-"作为合法值 allow_dash = len(qty_cols) >= 2 # 匹配规则:整数/浮点数开头,末尾可选带字母单位,数值和单位间允许空格 num_pattern = re.compile(r'^\d+(\.\d+)?\s*[a-zA-Z]*$') def check_row(row): for col in qty_cols: val = row[col] # 空值直接判定非法 if pd.isna(val): return row['line no'] # 统一转字符串去首尾空格做格式判断 val_str = str(val).strip() # AR为固定合法值 if val_str == 'AR': continue # 多列场景下"-"判定合法 if allow_dash and val_str == '-': continue # 匹配数值+单位格式,匹配通过则进入下一列校验 if num_pattern.match(val_str): continue # 所有合法分支未命中,返回当前行号 return row['line no'] # 所有qty列校验通过返回True return True # 逐行应用校验逻辑,返回和原表行顺序对齐的结果列表 return df.apply(check_row, axis=1).tolist() # 批量校验多页库存表示例 if __name__ == '__main__': # 将所有待校验的库存DataFrame按页顺序存入列表即可 inventory_tables = [df_multi_qty, df_single_qty] page_results = [] for table in inventory_tables: page_res = validate_qty_columns(table) page_results.append(page_res)
逻辑说明
- 正则规则已经覆盖不带单位的纯整数/浮点数、带
EA单位的整数、带FT/KG等任意计量单位的数值场景,不需要单独为每个单位写判断分支 - 函数会自动识别当前表的qty列数量,决定是否放开
"-"的合法权限,不需要手动标记表类型 - 返回的
page_results是按页存储的校验结果,每个子列表和对应表的行顺序完全对齐,合法行值为True,非法行值为对应行的line no - 如果需要把校验结果直接写回原表,执行
df['corr_qty'] = validate_qty_columns(df)即可
内容的提问来源于stack exchange,提问作者onlywynter
相关产品推荐
相关产品推荐

