如何用Python按匹配ID将数据从一个电子表格复制到另一个?
用Python填充Excel空白列的实现方案(Pandas/OpenPyXL)
优先方案:Pandas(高效无需手动迭代)
Pandas的向量化操作和合并功能可以彻底避免手动遍历行的繁琐,完美解决数据存储、迭代的问题。
步骤分解
- 读取两个Excel文件,转为DataFrame格式
- 将File2的ID与对应Field4/5数据构建成映射字典(或直接用合并方法)
- 用映射或合并逻辑填充File1的空白列
- 保存结果文件
代码实现(映射字典版)
import pandas as pd # 读取文件,替换为你的实际列名(比如ID列叫"用户ID",Field4叫"地址"等) df1 = pd.read_excel("File1.xlsx") df2 = pd.read_excel("File2.xlsx") # 构建ID到Field4/5的映射字典,一次性加载所有数据,避免反复查询 id_to_fields = df2.set_index("ID")[["Field4", "Field5"]].to_dict("index") # 仅填充空白单元格,保留原有非空数据 df1["Field4"] = df1.apply( lambda row: id_to_fields.get(row["ID"], {}).get("Field4") if pd.isna(row["Field4"]) else row["Field4"], axis=1 ) df1["Field5"] = df1.apply( lambda row: id_to_fields.get(row["ID"], {}).get("Field5") if pd.isna(row["Field5"]) else row["Field5"], axis=1 ) # 保存结果(建议存新文件,避免覆盖原文件) df1.to_excel("File1_filled.xlsx", index=False)
代码实现(合并版,更简洁)
如果不需要保留原空白列的严格判断,用左合并更高效:
import pandas as pd df1 = pd.read_excel("File1.xlsx") df2 = pd.read_excel("File2.xlsx") # 提取File2中需要的列,避免合并后多出无关数据 df2_clean = df2[["ID", "Field4", "Field5"]] # 左合并:保留File1所有行,匹配File2的数据 merged_df = df1.merge(df2_clean, on="ID", how="left", suffixes=("", "_from_file2")) # 填充空白:用File2的数据替换原空白,非空值保留 merged_df["Field4"] = merged_df["Field4"].fillna(merged_df["Field4_from_file2"]) merged_df["Field5"] = merged_df["Field5"].fillna(merged_df["Field5_from_file2"]) # 删除临时列并保存 merged_df.drop(columns=["Field4_from_file2", "Field5_from_file2"], inplace=True) merged_df.to_excel("File1_filled.xlsx", index=False)
备选方案:OpenPyXL(手动迭代,适合精细控制)
如果你需要逐行操作的场景,先将File2的数据预存到字典(解决反复遍历的性能问题),再处理File1。
步骤分解
- 加载两个Excel工作簿,获取对应工作表
- 一次性读取File2的ID与Field4/5数据,存入字典(避免每次查询都遍历File2)
- 遍历File1的每一行,仅填充空白的Field4/5单元格
- 保存修改后的File1
代码实现
from openpyxl import load_workbook import pandas as pd # 加载工作簿:File1需可写模式,File2只读即可 wb1 = load_workbook("File1.xlsx", read_only=False) ws1 = wb1.active wb2 = load_workbook("File2.xlsx", read_only=True) ws2 = wb2.active # 读取File2的表头,自动匹配列索引(避免硬编码列位置) headers = [cell.value for cell in ws2[1]] id_col = headers.index("ID") field4_col = headers.index("Field4") field5_col = headers.index("Field5") # 构建ID到Field4/5的映射字典 id_data = {} for row in ws2.iter_rows(min_row=2, values_only=True): id_val = row[id_col] id_data[id_val] = (row[field4_col], row[field5_col]) # 遍历File1的行,填充空白单元格 for row in ws1.iter_rows(min_row=2): current_id = row[id_col].value field4_cell = row[field4_col] field5_cell = row[field5_col] # 仅填充空白单元格 if pd.isna(field4_cell.value) or field4_cell.value is None: field4_cell.value = id_data.get(current_id, (None, None))[0] if pd.isna(field5_cell.value) or field5_cell.value is None: field5_cell.value = id_data.get(current_id, (None, None))[1] # 保存修改 wb1.save("File1_filled.xlsx")
关键注意事项
- 列名/列索引:务必替换为你实际的列名,避免硬编码错误
- 数据备份:操作前备份原文件,防止数据丢失
- 不匹配ID:两种方案都会保留原空白,不会强制填充不存在的ID数据
内容的提问来源于stack exchange,提问作者csaunders
相关产品推荐
相关产品推荐

