讲师中心 微信公众号

工具推荐

视频效率加速
updream

一键生成高质量推广成片

Seko
Seko

AI短剧一键生成成片

剧云
剧云

中文短剧剧本制作平台

Laper
Laper

剧本策划到成片协作

excel-mapping-replace

Polar Sponsor
爱发电 赞助
.NET 9.0

辅助处理excel表格,按映射表批量替换某列值

此技能遵循[excel-seafe-workflow] 四步法.

功能概述

此技能遵循[excel-seafe-workflow] 四步法.是一项面向实际任务的技能,主要用于映射匹配使用熊猫,值替换使用openpyxl(小文件)或XML(大文件).。它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。

核心要点

  • 使用时应结合输入条件选择合适的执行方式,核对必要参数、依赖环境与输出内容,并按原始要求处理异常情况。
  • 该技能适合需要稳定复用相关能力的场景,可作为自动化工作流的一部分,也便于后续检查、调整和扩展。
  • 从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。

使用与执行

实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。

结果检查与注意事项

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

This skill follows [[excel-safe-workflow]] four-step method. Mapping matching uses pandas, value replacement uses openpyxl (small files) or XML (large files). 本技能遵循 [[excel-safe-workflow]] 四步法。映射匹配用 pandas,值替换用 openpyxl(小文件)或 XML(大文件)。

Excel Mapping Replace / Excel 映射替换

功能

给一张映射表,把目标列中匹配的值全部替换。

映射表:                          目标列替换前 → 替换后:
  中国 → CN                      中国 → CN
  日本 → JP                      中国 → CN
  美国 → US                      日本 → JP
  德国 → DE                      中国 → CN
  ...                            ...

映射表中不存在的值保留原样,不会丢失数据。

第零步:需求解析

要素 用户说 默认值
目标列 "公开国别""状态列" 必须明确
映射关系 "中国→CN,日本→JP" / 粘贴列表 / 映射文件 必须明确
映射来源 对话口述 / 粘贴文本 / xlsx文件 对话口述

映射关系格式

# 对话直说(几个映射)
"中国换成CN,日本换成JP,美国换成US"

# 粘贴列表(几十个映射)
中国 → CN
日本 → JP
美国 → US
...

# 映射文件(几百个映射)
"用 国家代码表.xlsx 的 A列→B列 做映射"

第一步:勘察

import pandas as pd

FILE = '目标文件.xlsx'
TARGET_COL = '列名'

df = pd.read_excel(FILE)
print(f'总行数: {len(df)}')

vc = df[TARGET_COL].value_counts()
print(f'唯一值: {len(vc)}')
for k, v in vc.head(20).items():
    print(f'  {k}: {v}')

第二步:规划

  • 确认目标列和映射表
  • 统计有多少行会受影响(映射表 ∩ 列中的值)
  • 列出映射表中不存在的值(不会被改动)
  • 确认无误后执行

第三步:执行

⚠️ 禁止在 sharedStrings 层做全局替换。必须走 sheet 层 + 列号限定,只改目标列的 cell。

import pandas as pd
from openpyxl import load_workbook
from openpyxl.utils import get_column_letter
import os, shutil, re, time

FILE = '目标文件.xlsx'
TARGET_COL = '列名'
MAPPING = {'旧值1': '新值1', '旧值2': '新值2', ...}

# ====== 3.1 勘察 ======
df = pd.read_excel(FILE)
col_idx = list(df.columns).index(TARGET_COL) + 1  # 列号(1-based)
col_letter = get_column_letter(col_idx)

# 统计影响
affected = {k: v for k, v in df[TARGET_COL].value_counts().items() if k in MAPPING}
unmatched = {k: v for k, v in df[TARGET_COL].value_counts().items() if k not in MAPPING}

print(f'目标列: {TARGET_COL} ({col_letter}), 将替换:')
for k, v in affected.items():
    print(f'  {k} → {MAPPING[k]}: {v} 行')
if unmatched:
    print(f'n不在映射表中(保留原值):')
    for k, v in unmatched.items():
        print(f'  {k}: {v} 行')

# ====== 3.2 执行 ======
USE_XML = os.path.getsize(FILE) > 10 * 1024 * 1024  # >10MB

if USE_XML:
    # ====== XML 方案:sheet 层 + 列号限定 + inline 写入 ======
    print('n替换中(XML sheet 层方案)...')
    import zipfile
    from lxml import etree

    t0 = time.time()
    TMP = FILE.replace('.xlsx', '_mp_tmp')
    if os.path.exists(TMP): shutil.rmtree(TMP)
    os.makedirs(TMP)
    with zipfile.ZipFile(FILE, 'r') as z:
        z.extractall(TMP)

    S_NS = 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'
    parser = etree.XMLParser(remove_blank_text=False, huge_tree=True)
    ns = {'s': S_NS}

    # 读 sharedStrings 建立 si→text 映射(只读,用于解析 t="s" 的 cell)
    ss_path = os.path.join(TMP, 'xl', 'sharedStrings.xml')
    si_lookup = {}
    if os.path.exists(ss_path):
        ss_tree = etree.parse(ss_path, parser)
        for idx, si_elem in enumerate(ss_tree.findall('.//s:si', ns)):
            t_elem = si_elem.find('s:t', ns)
            si_lookup[idx] = t_elem.text if t_elem is not None else ''

    # 处理 sheet XML — 只在目标列上改值
    ws_dir = os.path.join(TMP, 'xl', 'worksheets')
    replaced = 0
    for sf in sorted(os.listdir(ws_dir)):
        if not sf.endswith('.xml'): continue
        sp = os.path.join(ws_dir, sf)
        tree = etree.parse(sp, parser)
        root = tree.getroot()

        for row_elem in root.findall('.//s:row', ns):
            if row_elem.get('r') == '1': continue  # 跳过表头
            for cell in row_elem.findall('s:c', ns):
                # 限定列号
                if not cell.get('r', '').startswith(col_letter):
                    continue

                # 获取当前文本值
                cell_type = cell.get('t', '')
                val = None
                if cell_type == 's':
                    v_elem = cell.find('s:v', ns)
                    if v_elem is not None and v_elem.text:
                        val = si_lookup.get(int(v_elem.text), '')
                else:
                    is_elem = cell.find('s:is', ns)
                    if is_elem is not None:
                        t_elem = is_elem.find('s:t', ns)
                        val = t_elem.text if t_elem is not None else ''

                if val is None or val not in MAPPING:
                    continue

                # 改为 inline 字符串(不创建新的 sharedString 引用)
                new_val = MAPPING[val]
                cell.set('t', 'inlineStr')
                for child in list(cell):
                    tag = child.tag.split('}')[-1]
                    if tag in ('v', 'f', 'is'): cell.remove(child)
                is_new = etree.SubElement(cell, '{'+S_NS+'}is')
                t_new = etree.SubElement(is_new, '{'+S_NS+'}t')
                t_new.text = new_val
                replaced += 1

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

    print(f'  替换 {replaced} 个单元格')

    # 打包
    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)
    print(f'  耗时: {time.time()-t0:.0f}s')

else:
    # ====== openpyxl 方案(小文件,简单可靠)======
    print('n替换中(openpyxl 方案)...')

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

    t0 = time.time()
    wb = load_workbook(FILE)
    ws = wb.active

    replaced = 0
    for row in range(2, ws.max_row + 1):
        cell = ws.cell(row=row, column=col_idx)
        if cell.value in MAPPING:
            cell.value = MAPPING[cell.value]
            replaced += 1
        if row % 50000 == 0:
            print(f'  进度: {row}/{ws.max_row}')

    wb.save(FILE)
    wb.close()
    print(f'  替换: {replaced} 个, 耗时: {time.time()-t0:.1f}s')

第四步:验证

df2 = pd.read_excel(FILE)
print(f'n替换后 [{TARGET_COL}] 分布:')
for k, v in df2[TARGET_COL].value_counts().items():
    marker = ' ← 新' if k in MAPPING.values() else ''
    print(f'  {k}: {v}{marker}')

# 确认未映射值没被修改
for old_val in unmatched:
    still_there = (df2[TARGET_COL] == old_val).sum()
    if still_there != unmatched[old_val]:
        print(f'  ❌ {old_val}: 预期{unmatched[old_val]}行, 实际{still_there}行')

从映射文件读取

# 从另一个 xlsx/csv 读取映射表
map_df = pd.read_excel('映射文件.xlsx')
MAPPING = dict(zip(map_df.iloc[:, 0], map_df.iloc[:, 1]))
# 或从 csv
# map_df = pd.read_csv('映射文件.csv')
# MAPPING = dict(zip(map_df['中文'], map_df['代码']))

注意事项

  1. 映射表不匹配的值不动:只替换映射表中存在的值,其余原样保留
  2. 精确匹配:不是包含匹配。中国 只匹配 中国,不匹配 中国北京
  3. ⚠️ XML 方案只在目标列上改值:通过列号限定 cell.get('r').startswith(col_letter),不会误伤其他列。禁止在 sharedStrings 层做全局替换
  4. 改值后写 inline string:替换后的值写为 内联字符串,不产生新的 sharedString 引用
  5. 操作前必备份:遵循 [[excel-safe-workflow]] 第零步——操作前自动备份(时间戳命名),成功后保留最新3份,失误后立即删除损坏文件并从备份恢复
  6. 文件被占用:如果目标文件正在 Excel 中打开,会保存失败。提示用户关闭后重试
  7. 大小写敏感:China ≠ china,如需不敏感需预处理
目录

热门AI工具

更多
DeepSeek

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

WorkBuddy

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

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

函子Zion

一款支持AI搭建、可视化编辑和多端发布的全栈无代码开发平台。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

豆包大模型

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

Flowith
Flowith Hot

Flowith是一款基于画布和智能体工作流的 AI 协作工作空间。

相关专题

更多
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.6万人学习

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

共28课时 | 3.6万人学习

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

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