如何用Python/Pandas区分Excel合并单元格与空白单元格?
用Pandas区分Excel空白单元格与合并后空白单元格并填充指定值
当用Pandas读取带合并单元格的Excel时,合并区域仅首单元格保留原值,其余均为NaN。但这些NaN分为两类:
- 合并产生的空白:属于合并区域内的非首单元格(比如你示例中的1a、1b对应单元格)
- 原生空白单元格:原本就无内容的单元格(比如示例中的1i)
要实现仅给原生空白单元格填充X,可按以下步骤操作:
步骤1:安装依赖
确保安装处理Excel的必要库:
pip install pandas openpyxl
步骤2:读取Excel并获取合并单元格信息
用openpyxl加载工作簿提取合并单元格范围,再结合Pandas的DataFrame处理:
import pandas as pd from openpyxl import load_workbook # 替换为你的文件路径 file_path = "your_excel_file.xlsx" # 读取Excel数据到DataFrame df = pd.read_excel(file_path, engine="openpyxl") # 加载工作簿,获取合并单元格范围 wb = load_workbook(file_path) ws = wb.active merged_ranges = [] # 遍历所有合并单元格,转换为Pandas可用的0起始索引范围 for merged_cell in ws.merged_cells.ranges: start_row = merged_cell.min_row - 1 end_row = merged_cell.max_row - 1 start_col = merged_cell.min_col - 1 end_col = merged_cell.max_col - 1 merged_ranges.append((start_row, end_row, start_col, end_col))
步骤3:标记合并产生的空白单元格
创建布尔矩阵,标记哪些NaN是合并导致的:
# 初始化布尔矩阵,默认所有单元格都不是合并空白 is_merged_blank = pd.DataFrame(False, index=df.index, columns=df.columns) # 遍历合并区域,标记非首单元格为合并空白 for start_row, end_row, start_col, end_col in merged_ranges: for row in range(start_row, end_row + 1): for col in range(start_col, end_col + 1): # 合并区域内,除第一个单元格外,其余都是合并产生的空白 if row != start_row or col != start_col: is_merged_blank.iloc[row, col] = True
步骤4:填充原生空白单元格
筛选出是NaN且不属于合并空白的单元格,填充X:
# 仅给原生空白单元格填充X df = df.mask(df.isna() & ~is_merged_blank, "X") # 保存处理后的文件 df.to_excel("filled_result.xlsx", index=False, engine="openpyxl")
批量处理多个表格
如果需要处理多个同类文件,可将逻辑封装为函数循环处理:
def process_excel(file_path, output_path): df = pd.read_excel(file_path, engine="openpyxl") wb = load_workbook(file_path) ws = wb.active merged_ranges = [] for merged_cell in ws.merged_cells.ranges: start_row = merged_cell.min_row - 1 end_row = merged_cell.max_row - 1 start_col = merged_cell.min_col - 1 end_col = merged_cell.max_col - 1 merged_ranges.append((start_row, end_row, start_col, end_col)) is_merged_blank = pd.DataFrame(False, index=df.index, columns=df.columns) for start_row, end_row, start_col, end_col in merged_ranges: for row in range(start_row, end_row + 1): for col in range(start_col, end_col + 1): if row != start_row or col != start_col: is_merged_blank.iloc[row, col] = True df = df.mask(df.isna() & ~is_merged_blank, "X") df.to_excel(output_path, index=False, engine="openpyxl") # 示例:处理多个文件 file_list = ["file1.xlsx", "file2.xlsx"] for idx, file in enumerate(file_list): process_excel(file, f"result_{idx+1}.xlsx")
内容的提问来源于stack exchange,提问作者João Victor Fernandes
相关产品推荐
相关产品推荐

