You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas中校验多列数据格式并合并校验结果至单列?

实现多规则校验结果的追加(而非覆盖)方案

我明白你现在的困扰——每次执行一条校验规则时,check列里之前的结果都会被覆盖,没法把多个校验问题用分号合并在一起对吧?下面给你两种可行的实现思路和代码:

方法一:逐规则定位行并追加内容

这种方式会逐个处理每条校验规则,只对符合条件的行追加提示文本,不会覆盖已有结果。

步骤1:准备示例数据

import pandas as pd
import numpy as np

# 构造你提供的示例数据集
data = {
    'id': [0,1,2,3,4,5,6],
    'room': ['A-102', np.nan, 'B309', 'C·102', 'E_1089', '27', '27'],
    'area': ['world', '24', np.nan, '25', 'hello', np.nan, np.nan],
    'situation': ['under construction', 'under construction', np.nan, 'under decoration', 'under decoration', 'under plan', np.nan]
}
df = pd.DataFrame(data)

步骤2:初始化check列

先把check列初始化为空字符串,方便后续追加内容:

df['check'] = ''

步骤3:逐条执行校验规则

规则1:校验room格式

# 匹配数字、字母、连字符,NaN视为无效
room_invalid = ~df['room'].str.match('^[a-zA-Z\d\-]*$', na=False)
# 对符合条件的行追加提示,已有内容则加分号分隔
df.loc[room_invalid, 'check'] = df.loc[room_invalid, 'check'].apply(
    lambda x: x + 'incorrect room name' if x == '' else x + '; incorrect room name'
)

规则2:校验area是否为数字

# 非NaN且不是纯数字的情况触发提示
area_invalid = df['area'].notna() & ~df['area'].str.contains('^\d+$')
df.loc[area_invalid, 'check'] = df.loc[area_invalid, 'check'].apply(
    lambda x: x + 'area is not numbers' if x == '' else x + '; area is not numbers'
)

规则3:校验situation包含指定内容

# 包含"under decoration"的情况触发提示
situation_match = df['situation'].str.contains('under decoration', na=False)
df.loc[situation_match, 'check'] = df.loc[situation_match, 'check'].apply(
    lambda x: x + 'decoration is in the content' if x == '' else x + '; decoration is in the content'
)

步骤4:处理空值(可选)

把没有校验问题的空字符串转为NaN,和你预期的输出格式一致:

df['check'] = df['check'].replace('', np.nan)

最终输出结果:

idroomareasituationcheck
0A-102worldunder constructionarea is not numbers; decoration is in the content
1NaN24under constructiondecoration is in the content
2B309NaNNaNNaN
3C·10225under decorationincorrect room name; decoration is in the content
4E_1089hellounder decorationarea is not numbers; decoration is in the content
527NaNunder planNaN
627NaNNaNNaN

方法二:用apply逐行处理(更直观)

如果你觉得逐规则定位行太繁琐,可以用apply函数逐行校验,把所有符合条件的提示收集到列表后再拼接:

def check_single_row(row):
    check_items = []
    # 规则1:校验room
    if pd.isna(row['room']) or not row['room'].match('^[a-zA-Z\d\-]*$'):
        check_items.append('incorrect room name')
    # 规则2:校验area
    if pd.notna(row['area']) and not row['area'].contains('^\d+$'):
        check_items.append('area is not numbers')
    # 规则3:校验situation
    if pd.notna(row['situation']) and 'under decoration' in row['situation']:
        check_items.append('decoration is in the content')
    # 拼接结果,无问题则返回NaN
    return '; '.join(check_items) if check_items else np.nan

df['check'] = df.apply(check_single_row, axis=1)

这个方法逻辑更清晰,和逐规则处理的结果完全一致。


为什么之前的代码会覆盖结果?

你之前用np.where或者df['check'].where()的时候,都是直接给整个check列重新赋值,这会完全覆盖掉之前已经写入的校验内容。而上面的两种方法都是只对符合条件的行进行内容追加,保留了之前的校验结果,从而实现多规则提示的合并。

内容的提问来源于stack exchange,提问作者ah bon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 21:17:38