讲师中心 微信公众号
AI工具推荐 视频效率加速

excel-deduplicate

Polar Sponsor
爱发电 赞助
.NET 9.0

辅助处理excel表格,去重——先查重再删除重复行

这种技巧将两个子技能协调起来:[[excel-find-dreplex]](只读查找) → [[excel-delate]](XML行删除).

功能概述

这种技巧将两个子技能协调起来:[[excel-find-dreplex]](只读查找) → [[excel-delate]](XML行删除).是一项面向实际任务的技能,主要用于Format 完全保存. → :[excel-find-dreplex](XX) → [[excel-find-dreplexs]]] – [[Xcel-dreplex-dplex]]].。它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。

核心要点

  • 从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。
  • 实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;
  • 若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。

使用与执行

执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;涉及批量任务时,还应保存进度,避免中断后重复操作。

结果检查与注意事项

该技能适合用于一次性任务,也可以接入自动化工作流,与其他技能或上层代理配合完成更完整的业务链路;在组合使用时,应明确每一步的输入输出关系,并避免不同步骤之间出现参数冲突。

This skill orchestrates two sub-skills: [[excel-find-duplicates]] (read-only find) → [[excel-delete]] (XML row deletion). Format fully preserved. 本技能编排两个子技能:[[excel-find-duplicates]](只读查重)→ [[excel-delete]](XML 行删除)。格式完整保留。

Excel Deduplication / Excel 去重

流程

excel-find-duplicates          XML 直接删除(不用 openpyxl)
      ↓                                ↓
pandas 只读扫描 → 行号集合 → 确认 → 解压 → lxml 移除  → 打包

完整执行脚本

import sys, os, time, zipfile, shutil, re
sys.stdout.reconfigure(encoding='utf-8')
import pandas as pd
from lxml import etree

FILE = '目标文件.xlsx'
KEY_COL = '列名'   # 去重关键列名(pandas 读取后的列名)
KEEP = 'first'      # 'first'=保留首次 / 'last'=保留末次

# ====== 第1步:只读查重(excel-find-duplicates) ======
print(f'① 扫描重复(按 "{KEY_COL}")...')
t0 = time.time()

df = pd.read_excel(FILE)
total = len(df)

mask = df[KEY_COL].duplicated(keep=KEEP)
dup_indices = df.index[mask].tolist()
dup_rows = [i + 2 for i in dup_indices]  # pandas 0-index → Excel 行号(+2 因为第1行=表头)

unique_count = df[KEY_COL].nunique()
print(f'  总行数: {total}')
print(f'  唯一值: {unique_count}')
print(f'  重复行: {len(dup_rows)} ({len(dup_rows)/total*100:.1f}%)')
print(f'  扫描耗时: {time.time()-t0:.0f}s')

if not dup_rows:
    print('✅ 无重复,无需去重')
    exit()

# ====== 第2步:确认 ======
print(f'n将删除 {len(dup_rows)} 行,保留 {total - len(dup_rows)} 行')
print(f'行号范围: {min(dup_rows)} ~ {max(dup_rows)}')
print('确认执行...')
dup_set = set(dup_rows)

# ====== 第3步:XML 直接删除 ======
print(f'n② XML 删除重复行...')
t0 = time.time()

# 3.1 备份
BACKUP = FILE.replace('.xlsx', '_backup.xlsx')
if not os.path.exists(BACKUP):
    shutil.copy2(FILE, BACKUP)

# 3.2 解压
TMP = FILE.replace('.xlsx', '_xml_tmp')
if os.path.exists(TMP):
    shutil.rmtree(TMP)
os.makedirs(TMP)
with zipfile.ZipFile(FILE, 'r') as z:
    z.extractall(TMP)

# 3.3 遍历 sheet XML,移除重复行
worksheets_dir = os.path.join(TMP, 'xl', 'worksheets')
parser = etree.XMLParser(remove_blank_text=False, huge_tree=True)
total_deleted = 0

for sf in sorted(os.listdir(worksheets_dir)):
    if not sf.endswith('.xml'):
        continue
    sp = os.path.join(worksheets_dir, sf)
    tree = etree.parse(sp, parser)
    root = tree.getroot()
    ns = {'s': 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'}

    deleted = 0
    for row_elem in root.findall('.//s:row', ns):
        if int(row_elem.get('r')) in dup_set:
            row_elem.getparent().remove(row_elem)
            deleted += 1

    if deleted == 0:
        continue

    # 清理合并单元格
    for mc in root.findall('.//s:mergeCells/s:mergeCell', ns):
        m = re.match(r'[A-Z]+(d+):[A-Z]+(d+)', mc.get('ref', ''))
        if m:
            r1, r2 = int(m.group(1)), int(m.group(2))
            if all(r in dup_set for r in range(r1, r2 + 1)):
                mc.getparent().remove(mc)

    # 更新 dimension
    dim = root.find('.//s:dimension', ns)
    if dim is not None:
        remaining = sorted([int(re.get('r')) for re in root.findall('.//s:row', ns)])
        all_cols = []
        for re_elem in root.findall('.//s:row', ns):
            for c in re_elem.findall('s:c', ns):
                m = re.match(r'([A-Z]+)', c.get('r', ''))
                if m: all_cols.append(m.group(1))
        if remaining and all_cols:
            max_col = max(all_cols, key=lambda x: (len(x), x))
            dim.set('ref', f'A1:{max_col}{max(remaining)}')

    sheet_xml = etree.tostring(root, xml_declaration=True, encoding='UTF-8', standalone=True)
    with open(sp, 'wb') as f:
        f.write(sheet_xml)

    total_deleted += deleted
    print(f'  {sf}: 删除 {deleted} 行')

# 3.4 重新打包
with zipfile.ZipFile(FILE, 'w', zipfile.ZIP_DEFLATED) as zout:
    for dirpath, _, filenames in os.walk(TMP):
        for fn in filenames:
            full = os.path.join(dirpath, fn)
            zout.write(full, os.path.relpath(full, TMP).replace('\', '/'))

shutil.rmtree(TMP)

elapsed = time.time() - t0
old_sz = os.path.getsize(BACKUP) / 1024 / 1024
new_sz = os.path.getsize(FILE) / 1024 / 1024
print(f'  删除耗时: {elapsed:.0f}s, {old_sz:.1f}MB → {new_sz:.1f}MB')

# ====== 第4步:验证 ======
print(f'n③ 验证...')
df2 = pd.read_excel(FILE)
dups_after = df2[KEY_COL].duplicated().sum()
print(f'  去重后: {len(df2)} 行')
print(f'  残留重复: {dups_after} {"✅" if dups_after == 0 else "❌ 还有重复!"}')

# 公式健康检查
from openpyxl import load_workbook
wb = load_workbook(FILE, read_only=True, data_only=True)
ws = wb.active
ref_errors = 0
for row_idx in range(1, min(50, ws.max_row + 1)):
    for col_idx in range(1, min(10, ws.max_column + 1)):
        v = ws.cell(row=row_idx, column=col_idx).value
        if v and isinstance(v, str) and '#REF!' in v:
            print(f'  ❌ #REF! at {ws.cell(row=row_idx, column=col_idx).coordinate}: {v}')
            ref_errors += 1
if ref_errors == 0:
    print(f'  公式健康: ✅ 无 #REF!')
wb.close()

与 excel-delete 的关系

去重的删除阶段直接内嵌 XML 操作(与 excel-delete 行模式共用同一套逻辑)。如果去重后发现还需额外删行,再单独调用 excel-delete。

注意事项

  1. 格式无损:只移除 XML 元素,不动 styles.xml / sharedStrings.xml
  2. 速度快:XML 方案比 openpyxl delete_rows() 快 10 倍以上
  3. 操作前必备份:遵循 [[excel-safe-workflow]] 第零步——操作前自动备份(时间戳命名),成功后保留最新3份,失误后立即删除损坏文件并从备份恢复
  4. 空值处理:关键列为 None 的多行只保留第一个
  5. 需要 lxml:pip install lxml(一次性)
目录

热门AI工具

更多
SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

讯飞智文

一款面向学习和办公场景的AI文档创作工具,可辅助生成PPT与Word文档,提高资料整理和内容制作效率。

相关专题

更多
Excel制作交互图表的方法 Excel交互式的图表教程大全
Excel制作交互图表的方法 Excel交互式的图表教程大全

Excel交互式图表可通过四种方法实现:一、用切片器控制数据透视图;二、结合下拉列表与INDEX-MATCH动态引用;三、用选项按钮绑定图表系列;四、利用动态命名区域配合OFFSET函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1820

2026.01.04

excel制作动态图表教程
excel制作动态图表教程

本专题整合了excel制作动态图表相关教程,阅读专题下面的文章了解更多详细教程。

205

2025.12.29

Excel图表制作全流程
Excel图表制作全流程

本专题整合了excel制作图表的相关教程,阅读专题下面的文章了解更多详细内容。

240

2025.12.23

excel xls与xlsx的区别
excel xls与xlsx的区别

本专题整合了excel中xls与xlsx的区别,阅读专题下面的文章了解更多详细内容。

357

2025.12.23

excel 绝对值
excel 绝对值

本专题整合了excel绝对值相关教程,阅读专题下面的文章了解更多详细内容。

839

2025.12.09

Excel如何制作一个动态交互式图表
Excel如何制作一个动态交互式图表

首先通过准备数据源并创建基础图表,再插入表单控件实现用户交互,接着使用INDEX公式提取对应数据,然后将图表数据源指向动态区域,最后优化布局与标题实现动态更新。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1738

2025.11.28

excel算方差教程
excel算方差教程

计算方差的步骤依次为:1. 计算平均值;2. 计算差异的平方;3. 求和平方值;4. 除以数据点数。想要了解更多相关内容,请阅读专题下面的文章。

4049

2025.05.27

怎么用excel制作标签
怎么用excel制作标签

用 Excel 制作标签,若为普通工作表标签,可右键单击标签选 “重命名” 来修改名称;选 “标签颜色” 设置颜色用于区分。若制作数据标签,比如地址标签,先在 Excel 整理好数据,再借助 Word 的邮件合并功能。在 Word 中依次操作:“邮件” 选项卡→“开始邮件合并”→“标签”,选好标签类型,导入 Excel 数据并设置格式,完成后打印 。

6551

2025.04.14

excel提取想要的数据
excel提取想要的数据

提取方法有很多种。直接定位:使用“定位”功能选择所需数据。筛选:根据条件筛选数据,显示满足条件的单元格。条件格式:突出显示满足特定条件的数据单元格。高级筛选:指定条件,将提取的数据粘贴到目标范围。公式:使用 index、if、sumif、countif 等函数从数据中提取值。vba 宏:编写脚本以自动提取数据,满足特定条件。

5430

2025.01.08

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Excel 教程
Excel 教程

共162课时 | 45.3万人学习

成为PHP架构师-自制PHP框架
成为PHP架构师-自制PHP框架

共28课时 | 3.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn