
本文介绍一种基于 pandas 的向量化方案,替代低效的 openpyxl 循环操作,可在毫秒级完成 8000 行 × 200 列表格中非空单元格的子字符串追加(如 a → a_05.04.2024 16:40.cas1 1),显著提升处理性能。
本文介绍一种基于 pandas 的向量化方案,替代低效的 openpyxl 循环操作,可在毫秒级完成 8000 行 × 200 列表格中非空单元格的子字符串追加(如 a → a_05.04.2024 16:40.cas1 1),显著提升处理性能。
在处理大型 Excel 表格(如 8k 行 × 200+ 列)时,使用 openpyxl 逐单元格遍历不仅代码冗长,且性能极差(原方案耗时超 20 分钟)。Pandas 提供了高效的向量化操作能力,可将该任务压缩至 374ms 左右(实测 7 次平均值),提速超 3000 倍。
核心思路:掩码 + 向量化拼接
整个流程分为三步:
- 构建布尔掩码:标记所有需修改的非空单元格(排除 NaN、空字符串及指定列);
- 提取并重构主列信息:从 Main_col 中提取时间戳与标识符(如 cas1 1_05.04.2024 16:40 → _05.04.2024 16:40.cas1 1);
- 广播式字符串拼接:利用 DataFrame.add() 实现按行广播的字符串连接。
完整实现代码
import pandas as pd
# 假设已读取 Excel 文件(跳过前 4 行,因目标从第 5 行开始)
df = pd.read_excel("input.xlsx", skiprows=4) # 注意:skiprows=4 对应第 5 行(0-indexed)
# Step 1: 构建掩码 —— 标记所有非空单元格,但排除 'Main_col' 列
mask = df.fillna('').ne('') # 将 NaN 转为空字符串后判断是否非空
mask['Main_col'] = False # 主列不参与追加操作
# Step 2: 重构 Main_col 内容(正则提取并重组)
# 原格式:cas1 1_05.04.2024 16:40 → 目标后缀:_05.04.2024 16:40.cas1 1
s = df['Main_col'].str.replace(
r'^([^ ]+) (\d)(_.*)$', # 匹配 "casX n_YYY"
r'\3.\1 \2', # 替换为 "_YYY.casX n"
regex=True
)
# Step 3: 向量化拼接(仅作用于 mask 为 True 的位置)
df[mask] = df.astype(str).add(s, axis=0)
✅ 关键说明:add(..., axis=0) 表示按行广播 —— 每行的 s.iloc[i] 将自动与该行所有匹配列的值拼接,无需循环。
处理起始行偏移(如从第 5 行开始)
若原始数据需从第 5 行(即索引 4)起生效,只需在掩码上屏蔽前 N=4 行:
N = 4 # 跳过前 4 行(对应 Excel 第 1–4 行),从第 5 行(index=4)开始处理 mask.iloc[:N] = False
注意事项与最佳实践
- 数据类型统一:务必调用 .astype(str),避免数值型列(如 123)与字符串拼接时报错;
- 正则健壮性:示例正则 r'^([^ ]+) (\d)(_.*)$' 假设 Main_col 格式严格为 "casX n_...";若格式多变,请增强正则或预清洗;
- 内存优化:对超大文件,可考虑 chunksize 分块读取,或使用 dtype=str 防止类型推断开销;
- 写回 Excel:处理完成后用 df.to_excel("output.xlsx", index=False) 保存,避免 openpyxl 写入瓶颈。
通过该方案,你不仅能彻底摆脱慢速循环,还能获得清晰、可维护、可扩展的数据处理逻辑 —— 这正是 Pandas 向量化哲学的核心价值。











