使用Python自动标记Excel中的重复项、缺失值与逻辑错误

 更新时间:2026年06月22日 09:38:10   作者:小庄-Python办公  
本文介绍如何利用Python自动化检测Excel数据质量,快速标记重复项、缺失值与逻辑错误,通过pandas和openpyxl实现三类核心检查:1)使用duplicated()检测重复数据;2)通过isna()识别空值;3)基于业务规则校验异常值,需要的朋友可以参考下

场景引入

收到一份 3000 行的销售数据,领导让你检查数据质量。手动检查需要逐一核对:有没有重复录入?有没有漏填的字段?金额会不会是负数?日期是不是写错了?

用 Python,你只需 5 分钟写好脚本,10 秒跑出检测报告,并且每次有新数据都可以直接复用。

技术原理

数据质检的核心就是三类检查:

检查类型检查内容pandas 方法
重复检测同一行数据完全相同或关键字段重复duplicated()
缺失检测必填字段为空isna(), isnull()
逻辑检测违反业务规则的值(如负数金额、未来日期)布尔条件过滤
原始数据
  ↓
[重复检测] → 标记重复行
  ↓
[缺失检测] → 标记缺失字段
  ↓
[逻辑检测] → 标记异常值
  ↓
生成检测报告 + 高亮问题行

环境准备

pip install pandas openpyxl

完整代码

import pandas as pd
import numpy as np
from openpyxl import load_workbook
from openpyxl.styles import PatternFill

def data_quality_check(input_file, required_columns=None, rules=None, output_file="数据质检报告.xlsx"):
    """
    对 Excel 数据进行质量检查,输出检测报告

    参数:
        input_file: 待检查的 Excel 文件
        required_columns: 必填字段列表
        rules: 自定义规则字典,如 {'金额': '>=0', '年龄': '18-65'}
        output_file: 输出报告文件名
    """
    df = pd.read_excel(input_file, engine='openpyxl')
    print(f"总数据: {len(df)} 行 × {len(df.columns)} 列\n")

    # ==================== 1. 重复项检测 ====================
    print("=" * 50)
    print("【1. 重复项检测】")

    # 完全重复的行
    duplicate_mask = df.duplicated(keep='first')
    duplicate_count = duplicate_mask.sum()
    print(f"完全重复行: {duplicate_count} 行")

    if duplicate_count > 0:
        # 记录重复行
        df['是否重复'] = duplicate_mask

    # ==================== 2. 缺失值检测 ====================
    print("\n【2. 缺失值检测】")

    missing_report = df.isnull().sum()
    missing_report = missing_report[missing_report > 0]

    if len(missing_report) > 0:
        for col, count in missing_report.items():
            pct = count / len(df) * 100
            print(f"  {col}: {count} 个缺失 ({pct:.1f}%)")
    else:
        print("  无缺失值 ✓")

    # 必填字段检查
    if required_columns:
        for col in required_columns:
            if col in df.columns:
                missing = df[col].isna().sum()
                blank = (df[col].astype(str).str.strip() == '').sum()
                total_issues = missing + blank
                if total_issues > 0:
                    print(f"  ⚠ 必填字段 '{col}' 有 {total_issues} 个空值!")
                    df[f'{col}_必填缺失'] = df[col].isna() | (df[col].astype(str).str.strip() == '')

    # ==================== 3. 逻辑错误检测 ====================
    print("\n【3. 逻辑错误检测】")

    if rules:
        for col, rule in rules.items():
            if col not in df.columns:
                print(f"  跳过: 列 '{col}' 不存在")
                continue

            try:
                if rule.startswith('>='):
                    threshold = float(rule[2:])
                    mask = df[col] < threshold
                    df[f'{col}_逻辑异常'] = mask
                    count = mask.sum()
                    print(f"  {col} < {threshold}: {count} 行异常")

                elif rule.startswith('<='):
                    threshold = float(rule[2:])
                    mask = df[col] > threshold
                    df[f'{col}_逻辑异常'] = mask
                    count = mask.sum()
                    print(f"  {col} > {threshold}: {count} 行异常")

                elif '-' in rule:
                    min_val, max_val = rule.split('-')
                    min_val, max_val = float(min_val), float(max_val)
                    mask = (df[col] < min_val) | (df[col] > max_val)
                    df[f'{col}_逻辑异常'] = mask
                    count = mask.sum()
                    print(f"  {col} 不在 [{min_val}-{max_val}]: {count} 行异常")

                elif rule == '>0':
                    mask = df[col] <= 0
                    df[f'{col}_逻辑异常'] = mask
                    count = mask.sum()
                    print(f"  {col} <= 0: {count} 行异常")

            except Exception as e:
                print(f"  规则执行失败 {col}: {e}")

    # ==================== 4. 生成报告 ====================
    print("\n" + "=" * 50)
    print("【4. 生成质检报告】")

    # 找出所有标记列(异常标记)
    flag_columns = [col for col in df.columns if col.endswith(('_重复', '_缺失', '_必填缺失', '_逻辑异常'))]

    if flag_columns:
        # 只要有任何一个标记为 True,就认为是问题行
        df['是否有问题'] = df[flag_columns].any(axis=1)
        issue_count = df['是否有问题'].sum()
        print(f"问题行总数: {issue_count} / {len(df)} ({issue_count/len(df)*100:.1f}%)")

        # 分离正常数据和问题数据
        issue_df = df[df['是否有问题'] == True]
        clean_df = df[df['是否有问题'] == False]

        # 保存问题数据
        issue_df.drop(columns=['是否有问题'] + flag_columns, inplace=True, errors='ignore')
        issue_df.to_excel(output_file.replace('.xlsx', '_问题数据.xlsx'), index=False, engine='openpyxl')
        print(f"问题数据已保存: {output_file.replace('.xlsx', '_问题数据.xlsx')}")

    # 保存完整报告
    df.to_excel(output_file, index=False, engine='openpyxl')
    print(f"完整报告已保存: {output_file}")

    return df


# ==================== 使用示例 ====================
if __name__ == "__main__":
    # 执行数据质检
    data_quality_check(
        input_file="销售数据表.xlsx",
        required_columns=["工号", "姓名", "部门", "金额"],  # 必填字段
        rules={
            "金额": ">=0",           # 金额不能为负数
            "数量": ">0",            # 数量必须大于 0
            "年龄": "18-65",         # 年龄范围 18-65
            "折扣率": "0-1",         # 折扣率 0-1 之间
        },
        output_file="数据质检报告.xlsx"
    )

进阶技巧

技巧 1:用 openpyxl 在 Excel 中高亮问题行

def highlight_issues(excel_file):
    """用红色背景高亮有问题的行"""
    wb = load_workbook(excel_file)
    ws = wb.active
    red_fill = PatternFill(start_color='FFC7CE', fill_type='solid')

    # 假设"是否有问题"列在第 N 列
    issue_col = 'N'

    for row in range(2, ws.max_row + 1):
        if ws[f'{issue_col}{row}'].value == True:
            for cell in ws[row]:
                cell.fill = red_fill

    wb.save(excel_file)

技巧 2:自动生成数据质量评分

# 计算数据质量分数(100 分制)
total_cells = len(df) * len(df.columns)
missing_cells = df.isnull().sum().sum()
duplicate_rows = df.duplicated().sum()

quality_score = 100 - (missing_cells / total_cells * 50) - (duplicate_rows / len(df) * 50)
print(f"数据质量评分: {quality_score:.1f} / 100")

技巧 3:异常值检测(统计学方法)

使用 3σ 原则自动识别离群值:

def detect_outliers(df, column):
    """检测数值列的异常值(3σ 原则)"""
    mean = df[column].mean()
    std = df[column].std()
    lower = mean - 3 * std
    upper = mean + 3 * std
    outliers = df[(df[column] < lower) | (df[column] > upper)]
    print(f"{column} 异常值: {len(outliers)} 行 (范围: {lower:.2f} ~ {upper:.2f})")
    return outliers

常见问题

Q1:日期列的缺失值检测不到?

Excel 中的日期可能是空字符串 “” 或 “0” 而不是 NaN。

解决

# 空字符串也视为缺失
df['日期'] = df['日期'].replace('', pd.NaT)
missing = df['日期'].isna().sum()

Q2:数值列中混入了文本?

# 尝试将列转为数值,无法转换的会变成 NaN
df['金额'] = pd.to_numeric(df['金额'], errors='coerce')
# 然后检查新产生的 NaN
print(f"非数值单元格: {df['金额'].isna().sum()}")

Q3:如何处理大小写不一致(“北京” vs “beijing”)?

df['城市'] = df['城市'].str.upper().str.strip()

总结

检测类型核心方法输出
重复检测df.duplicated()布尔掩码
缺失检测df.isnull().sum()每列缺失统计
必填检查自定义列列表空值行标记
逻辑检测布尔条件过滤异常值行标记
异常值3σ 原则 / 阈值判断离群点识别

本节掌握了数据质量检测的自动化方法,包括重复、缺失、逻辑三大类检查。这是数据清洗的必要前置步骤,确保后续分析的准确性。

以上就是Python自动标记Excel中的重复项、缺失值与逻辑错误的详细内容,更多关于Python自动化检测Excel数据质量的资料请关注脚本之家其它相关文章!

相关文章

  • python 移动图片到另外一个文件夹的实例

    python 移动图片到另外一个文件夹的实例

    今天小编就为大家分享一篇python 移动图片到另外一个文件夹的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-01-01
  • Django使用django-simple-captcha做验证码的实现示例

    Django使用django-simple-captcha做验证码的实现示例

    这篇文章主要介绍了Django使用django-simple-captcha做验证码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • 深入解析Python中浮点数计算的精度问题与解决方案

    深入解析Python中浮点数计算的精度问题与解决方案

    本文深入解析了Python中浮点数计算的精度问题,特别是0.1+0.2不等于0.3的现象,下文会通过实际案例展示浮点数陷阱在循环控制,金融计算等场景中的风险并提供了三种解决方案,感兴趣的小伙伴可以了解下
    2026-01-01
  • Keras之自定义损失(loss)函数用法说明

    Keras之自定义损失(loss)函数用法说明

    这篇文章主要介绍了Keras之自定义损失(loss)函数用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-06-06
  • 如何利用python将一个py文件变成一个软件详解

    如何利用python将一个py文件变成一个软件详解

    在我们完成一个Python项目或一个程序时,希望将Python的py文件打包成在Windows系统下直接可以运行的exe程序,下面这篇文章主要给大家介绍了关于如何利用python将一个py文件变成一个软件的相关资料,需要的朋友可以参考下
    2023-04-04
  • Python中inplace、subset参数的意义及说明

    Python中inplace、subset参数的意义及说明

    这篇文章主要介绍了Python中inplace、subset参数的意义及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • Python异常处理操作实例详解

    Python异常处理操作实例详解

    这篇文章主要介绍了Python异常处理操作,结合实例形式分析了Python异常处理的相关原理、操作语句与使用技巧,需要的朋友可以参考下
    2018-05-05
  • 使用Python制作一个恶意软件删除工具

    使用Python制作一个恶意软件删除工具

    这篇文章主要为大家详细介绍了如何使用Python制作一个恶意软件删除工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-02-02
  • Python实现暴力破解有密码的zip文件的方法

    Python实现暴力破解有密码的zip文件的方法

    这篇文章主要介绍了Python实现暴力破解有密码的zip文件的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • python 提取文件的小程序

    python 提取文件的小程序

    在做网站项目时,开发经常要给工程一个升级包,包含本次修改的内容,这个升级包的内容就是tomcat的发布目录下的文件;
    2009-07-07

最新评论