Python实现多Excel文件按指定映射表批量重命名列名
解决方案:正确匹配数据文件与映射表 + 适配同类别多文件
原代码核心问题
- 双重循环遍历所有文件和所有工作表,导致每个数据文件都会被所有工作表的映射处理一遍,完全没实现“文件-对应工作表”的匹配逻辑。
- 没有针对同类别多文件(如
phu_luc_chung1、phu_luc_chung2)的匹配规则。
解决思路
- 预加载所有映射表:一次性读取
table_name.xlsx的所有工作表,把每个工作表的旧列名-新列名映射存成字典,避免重复读文件。 - 建立文件-工作表的匹配规则:假设工作表名是类别标识,数据文件名包含该类别名(比如
phu_luc_chung1包含phu_luc_chung,对应同名工作表),用模糊匹配来关联。 - 遍历数据文件,匹配对应映射:对每个数据文件,找到对应的映射字典,再执行列名重命名。
修改后的代码
import pandas as pd import os import glob # 配置参数 mapping_file = "table_name.xlsx" data_path = r"E:\folder" # 用r前缀避免转义字符问题 # 1. 预加载所有工作表的映射字典 mapping_dict = {} with pd.ExcelFile(mapping_file, engine='openpyxl') as xls: for sheet_name in xls.sheet_names: # 读取当前工作表的映射关系 df_mapping = pd.read_excel(xls, sheet_name=sheet_name) # 生成旧列名(转小写)到新列名的映射,和数据文件的列名小写对应 rename_map = dict(zip(df_mapping["Old"].str.lower(), df_mapping["New"])) mapping_dict[sheet_name] = rename_map # 2. 获取所有数据文件,排除映射表本身 data_files = [f for f in glob.glob(os.path.join(data_path, '*.xlsx')) if os.path.basename(f) != mapping_file] # 3. 遍历每个数据文件,匹配对应映射表 for file_path in data_files: file_name = os.path.basename(file_path).lower() # 转小写,避免大小写匹配问题 matched_sheet = None # 模糊匹配:找文件名包含的工作表名(处理同类别多文件) for sheet_name in mapping_dict.keys(): if sheet_name.lower() in file_name: matched_sheet = sheet_name break if not matched_sheet: print(f"警告:文件 {os.path.basename(file_path)} 未找到对应映射表,跳过") continue # 读取数据文件并处理列名 df = pd.read_excel(file_path, engine='openpyxl') # 列名转小写,和映射表的旧列名统一 df.columns = [col.lower() for col in df.columns] # 应用映射重命名列 df_renamed = df.rename(columns=mapping_dict[matched_sheet]) # 这里可以添加保存到数据库/保存为新文件的逻辑 print(f"已处理文件:{os.path.basename(file_path)},使用映射表:{matched_sheet}") print(df_renamed.head(10))
关键细节说明
- 预加载映射表:只读取一次
table_name.xlsx,提升运行效率,尤其是文件较多时。 - 模糊匹配逻辑:通过判断工作表名是否包含在文件名中,自动适配
phu_luc_chung1、phu_luc_chung2这类同类别多文件。如果你的匹配规则不同(比如文件名前缀完全对应工作表名),可以修改匹配逻辑。 - 大小写统一:把文件名、列名都转成小写,避免因大小写不一致导致的匹配失败。
- 异常处理:添加了未找到对应映射表的提示,避免程序崩溃。
内容的提问来源于stack exchange,提问作者Henry
相关产品推荐
相关产品推荐

