1. 问题背景:为什么要批量分列指定工作表数据
本文主题是 对多个工作簿中指定工作表的数据进行分列。这个场景属于 excel 数据清洗里非常典型的一类:一列里塞了多个信息,中间用某个分隔符连接,现在需要把它拆成多个独立字段。
比如原始数据中有一列叫 信息,内容长这样:张三*13800000000*销售。这类数据对人来说能看懂,但对后续筛选、统计、透 视分析并不友好。真正适合分析的数据结构,应该把它拆成 姓名、手机号、部门 三列。
这张图展示了本文的整体主题:使用 python 批量处理多个 excel 工作簿,并对指定工作表中的目标列进行自动分列。

从这张图中我们可以看出,本文并不是处理一个单独的 excel 文件,而是面向多个工作簿批量执行同一套数据清洗规则。 这类任务的本质,是把“手工点 excel 分列”变成“脚本批量拆列”。
这里最容易出问题的地方,是只关注 split 这一句代码,却忽略了批量处理前后的完整链路。真实办公环境中,除了拆列本身,还要考虑文件遍历、临时文件过滤、目标 sheet 是否存在、目标列是否存在、输出文件是否覆盖原文件等问题。
2. 应用场景:一列信息拆成多列字段
分列最常见的场景,就是一个字段里混合了多个信息。比如姓名、手机号、部门被拼在同一列里;或者产品、型号、颜色被拼在同一列里;再或者省、市、区被拼在同一列里。
这张图展示了最典型的分列效果:把一列“信息”拆成多个独立字段。

从这张图中我们可以看出,分列前的数据虽然紧凑,但字段没有结构;分列后的数据变成了姓名、手机号、部门三列,后续就可以直接筛选部门、校验手机号、按人员统计数据。
推荐把分列理解成“数据结构化”的动作,而不是简单的字符串拆分。如果只看字符串,它只是把 * 前后的内容切开;但从办公自动化角度看,它是在把不可分析的数据整理成可统计、可筛选、可建模的数据。
典型适用场景可以总结为下面几类:
1. 人员信息:姓名*手机号*部门
2. 商品信息:产品*型号*颜色
3. 地址信息:省*市*区
4. 项目信息:项目编号*项目名称*负责人
5. 资产信息:资产编号*使用人*所在部门
只要原始字段具有稳定分隔符,并且每一段含义相对固定,就可以考虑用 pandas 的 str.split() 进行自动拆分。
3. 核心原理:split、drop、concat 三步完成结构化
这个案例的核心逻辑其实很清楚:先用 split 把原始列拆成多列,再用 drop 删除原来的混合列,最后用 concat 把拆出来的新列拼回原表。
这张图展示了 pandas 分列清洗的核心逻辑:split 拆列、drop 删除原列、concat 拼回新列。

从这张图中我们可以看出,分列并不是单独的一步操作,而是一组连续的数据整理动作。 如果只拆列不删除原列,数据会重复;如果拆完不拼回原表,原有字段和新字段就无法形成完整结果。
核心代码如下:
split_df = df[split_col].astype(str).str.split(sep, expand=true) split_df.columns = new_cols df = df.drop(columns=[split_col]) df = pd.concat([df, split_df], axis=1)
这里有三个关键点。第一,astype(str) 是为了把目标列统一转成字符串,避免数字、空值、混合类型导致拆分不稳定。第二,expand=true 会让拆分结果直接变成一个 dataframe。第三,axis=1 表示按列方向拼接,也就是横向扩展字段。
如果拆分后的列数和你设置的新列名数量不一致,代码就会报错。例如你设置了 ["姓名", "手机号", "部门"] 三个列名,但某些单元格实际拆出来 2 段或 4 段,就会出现列数不匹配的问题。这个问题不是语法问题,而是原始数据质量问题。
4. 详细流程:从读取文件到写出新文件
在批量处理多个 excel 文件时,不能只写分列代码。完整流程应该包括:遍历文件夹、跳过临时文件、读取指定工作表、检查目标列、执行分列、删除原列、拼接新列、写出到新目录。
这张图展示了批量分列的完整处理流程,从读取工作簿到输出新文件,每一步都对应脚本中的关键动作。

从这张图中我们可以看出,一个稳定的批量脚本一定要有“过滤”和“校验”。比如跳过 ~$ 开头的 excel 临时文件,检查目标列是否存在,这些步骤看似不起眼,但能显著减少批处理报错。
完整代码如下,实际使用时主要修改 5 个参数:输入文件夹、目标工作表名、需要拆分的列、分隔符、新列名。
import os
import pandas as pd
# ====== 根据实际情况修改 ======
folder_path = r"e:\file\target" # 原始 excel 文件夹
sheet_name = "sheet1" # 需要处理的工作表名称
split_col = "信息" # 需要拆分的原始列
sep = "*" # 分隔符
new_cols = ["姓名", "手机号", "部门"] # 拆分后的新列名
out_folder = r"e:\file\split_out" # 输出目录,建议不要覆盖原文件
# ============================
os.makedirs(out_folder, exist_ok=true)
for file in os.listdir(folder_path):
# 1. 跳过 excel 临时文件
if file.startswith("~$"):
continue
# 2. 只处理 excel 文件
if not file.lower().endswith((".xlsx", ".xls", ".xlsm")):
continue
full_path = os.path.join(folder_path, file)
# 3. 读取指定工作表
df = pd.read_excel(full_path, sheet_name=sheet_name)
# 4. 判断目标列是否存在
if split_col not in df.columns:
print(f"跳过:{file},缺少列:{split_col}")
continue
# 5. 拆列
split_df = df[split_col].astype(str).str.split(sep, expand=true)
# 6. 设置拆分后的列名
split_df.columns = new_cols
# 7. 删除原列
df = df.drop(columns=[split_col])
# 8. 拼接新列
df = pd.concat([df, split_df], axis=1)
# 9. 写出到新文件
out_path = os.path.join(out_folder, file)
df.to_excel(out_path, index=false)
print(f"分列完成:{file} -> {out_path}")
推荐输出到新目录,而不是直接覆盖原文件。批量数据清洗一旦处理错误,覆盖原文件会让回退变得麻烦。先输出到 split_out 目录,确认结果没问题后,再决定是否替换原文件。
5. 关键代码解析:每一步为什么这样写
5.1 为什么要先 astype(str)
excel 中的数据类型经常不稳定。比如手机号可能被识别成数字,空白单元格可能变成 nan,某些字段可能是文本和数字混合。如果直接使用 str.split(),可能出现不符合预期的结果。
df[split_col].astype(str)
astype(str) 的作用,是先把这一列统一成字符串,再执行分隔符拆分。这一步不是为了好看,而是为了让批量处理更稳定。
5.2 expand=true 为什么重要
str.split() 默认会把每个单元格拆成列表,但这不是我们最终需要的表格结构。我们希望拆出来的结果直接变成多列,因此要设置 expand=true。
split_df = df[split_col].astype(str).str.split(sep, expand=true)
如果 expand=false,每个单元格里会是一个列表;如果 expand=true,pandas 会直接返回一个新的 dataframe。 做 excel 分列时,通常优先使用 expand=true。
5.3 drop 删除原列,避免重复信息
原来的 信息 列已经被拆成了姓名、手机号、部门。如果继续保留原列,结果表会同时存在混合字段和结构化字段,容易造成冗余。
df = df.drop(columns=[split_col])
如果后续要追溯原始数据,可以先备份原文件,不建议在结果表里保留过多重复字段。否则表格看起来字段很多,但有效信息并没有增加。
5.4 concat 按列拼接新字段
拆出来的新列需要拼回原来的 dataframe 中。这里使用 pd.concat(),并设置 axis=1,表示按列拼接。
df = pd.concat([df, split_df], axis=1)
如果 axis=0,表示按行拼接;如果 axis=1,表示按列拼接。 分列后的字段是横向扩展,所以这里必须使用 axis=1。
6. 效果验证:不要只看脚本有没有报错
脚本运行完成,不代表数据处理一定正确。批量分列任务至少要验证三个方面:输出文件数量是否正确、目标列是否已经被拆开、拆分后的字段是否和原始信息对应。
可以先检查输出目录中的文件数量:
import os
out_folder = r"e:\file\split_out"
files = [f for f in os.listdir(out_folder) if f.lower().endswith((".xlsx", ".xls", ".xlsm"))]
print(f"输出文件数量:{len(files)}")
也可以读取一个输出文件,检查字段是否存在:
import pandas as pd test_file = r"e:\file\split_out\示例.xlsx" df = pd.read_excel(test_file) print(df.columns.tolist()) print(df.head())
推荐至少抽查 2 到 3 个输出文件。尤其是批量处理多个来源文件时,不同文件的数据格式可能存在细微差异。只验证一个文件,容易漏掉异常样本。
如果希望更稳,可以在脚本里加入处理日志:
log_list = []
log_list.append({
"文件名": file,
"处理结果": "成功",
"拆分列": split_col,
"输出路径": out_path
})
对于办公自动化脚本,日志就是证据链。当别人问“哪些文件处理过、哪些文件跳过、为什么跳过”时,日志比口头解释更可靠。
7. 常见问题与踩坑记录
7.1 拆分后的列数和新列名数量不一致
这是最常见的问题。比如你设置了三个新列名,但某一行数据只有两个分隔段,或者有一行数据多了一个 *,就可能导致列数不一致。
遇到这种情况,不要急着改代码,先检查原始数据是否规范。数据源不稳定时,脚本应该增加校验,而不是假设每一行都完全符合格式。
可以先查看实际拆出来多少列:
split_df = df[split_col].astype(str).str.split(sep, expand=true) print(split_df.shape)
7.2 分隔符可能是正则特殊字符
在较新的 pandas 版本中,str.split() 的参数涉及正则解释。如果分隔符是 *、|、. 这类特殊字符,要特别注意是否被当成正则符号处理。
如果分隔符只是普通字符,建议明确设置 regex=false。
split_df = df[split_col].astype(str).str.split(sep, expand=true, regex=false)
7.3 空值被转换成字符串 nan
使用 astype(str) 后,空值可能会变成字符串 "nan"。如果对结果要求比较严格,可以在拆分前先填充空值。
df[split_col] = df[split_col].fillna("")
split_df = df[split_col].astype(str).str.split(sep, expand=true)
这里的判断取决于业务规则。如果空值本来就应该保留为空,就用 fillna("");如果空值代表异常数据,就应该单独记录并提示。
7.4 不建议直接覆盖原文件
批量清洗数据时,直接覆盖原始 excel 风险很高。尤其是数据分列、删除原列、重新写出这种操作,一旦逻辑错了,原文件也可能被破坏。
我的建议是:原文件只读,处理结果写到新目录。这也是批量脚本最基本的安全边界。
8. 举一反三:一列数据也可以拆成多行
前面讲的是把一列拆成多列,属于横向扩展。但有些场景下,我们不是想拆成姓名、手机号、部门三列,而是想把一列中的多个值纵向展开成多行。
这张图展示了进阶场景:把一列数据通过 split、转置和 stack 拆成多行。

从这张图中我们可以看出,横向拆列和纵向拆行的思路不同。横向拆列会增加列数,纵向拆行会增加行数。 选择哪种方式,取决于后续数据分析需要的是“字段结构”还是“明细记录”。
示例代码如下:
import pandas as pd
df = pd.dataframe({
"信息": [
"张三*13800000000*销售",
"李四*13900000000*财务",
"王五*13700000000*市场"
]
})
# 1. 先拆成多列
split_df = df["信息"].astype(str).str.split("*", expand=true, regex=false)
# 2. stack 纵向展开
long_df = split_df.stack().reset_index()
# 3. 重命名字段
long_df.columns = ["原行号", "拆分序号", "拆分值"]
print(long_df)
输出结果会保留原行号和拆分序号,这样就能知道每个拆分值来自原始数据的哪一行。
如果后续要做明细化统计、标签展开、关键词拆分,这种“一列拆多行”的方式会更合适。比如一个单元格里有多个标签,用 * 或逗号隔开,拆成多行后就可以按标签做统计。
9. 总结与进阶建议
这一篇的核心,不是简单记住 str.split(),而是理解一套完整的数据清洗流程:读取指定工作表、定位目标列、拆分字段、删除原列、拼回新列、输出新文件、最后验证结果。
本文最重要的三个动作是:split 负责拆列,drop 负责删除原始混合列,concat 负责把新字段拼回原表。 这三个动作组合起来,才是真正可复用的 pandas 分列清洗模板。
如果要把这个脚本继续升级,我建议增加三类能力:第一,增加异常日志,记录哪些文件缺少目标列;第二,增加列数校验,防止拆分结果和新列名不匹配;第三,增加结果汇总表,统一记录每个文件的处理状态。
最后提醒一句:批量脚本不要一上来就处理正式文件。先复制几份样本文件测试,确认分列结果、字段顺序、输出文件都正确,再扩大处理范围。自动化不是为了冒险,而是为了让重复工作更稳定、更可控。
以上就是python批量处理excel工作簿中指定工作表的数据并分列的详细内容,更多关于python excel数据分列的资料请关注代码网其它相关文章!
发表评论