Python删除Excel指定行报错:TypeError: string indices must be integers
问题解决:删除Excel中Loc列以Totals开头的行并修复TypeError错误
错误原因
你之前的小测试代码里,path是pandas DataFrame对象,所以能用path['Loc']索引列;但完整脚本中path被赋值成了字符串类型的文件路径,对字符串用列名索引自然会抛出TypeError: string indices must be integers错误。
修改后的完整脚本
#----------------------------------------------------------------------------------------------------------------------------------- # 用途:提取定量和定性数据并清洗,之后将报表发送至Microsoft SQL Server处理 # 流程:读取文件 -> 转换格式 -> 清理表格 -> 格式适配SQL -> 发送至数据库 #----------------------------------------------------------------------------------------------------------------------------------- import pandas as pd import openpyxl import time # 需预先安装openpyxl库 # time库用于添加加载延迟 #----------------------------------------------------------------------------------------------------------------------------------- print('开始数据清理...') # 读取.xls文件并转为DataFrame # NextGen导出的是Excel 93-03格式的.xls,需转为.xlsx方便后续操作 read_file = pd.read_excel('IMPORTED_FILE.xls') #----------------------------------------------------------------------------------------------------------------------------------- print("-" * 20) # 将文件另存为.xlsx格式 read_file.to_excel('CONVERTED_FILE.XLSX', index = False, header = True) #----------------------------------------------------------------------------------------------------------------------------------- # 定义文件路径 path = 'CONVERTED_FILE.XLSX' # 统计初始行列数 wb_obj = openpyxl.load_workbook(path) sheet_obj = wb_obj.active print('初始行数: ', sheet_obj.max_row) print('初始列数: ', sheet_obj.max_column) max_col = sheet_obj.max_column print("-" * 20) time.sleep(1) #----------------------------------------------------------------------------------------------------------------------------------- # 删除NextGen自动生成的前4行标题 wb = openpyxl.load_workbook(path) sheet = wb['Sheet1'] sheet.delete_rows(sheet.min_row, 4) wb.save(path) #----------------------------------------------------------------------------------------------------------------------------------- # 统计删除前4行后的行列数 wb_obj = openpyxl.load_workbook(path) sheet_obj = wb_obj.active print('Alpha清理后行数: ', sheet_obj.max_row) print('Alpha清理后列数: ', sheet_obj.max_column) max_col = sheet_obj.max_column time.sleep(1) #----------------------------------------------------------------------------------------------------------------------------------- print("-" * 20) print('移除空行(Alpha阶段)') # 移除全空行 def remove_empty_rows(sheet): # 遍历所有行 for row in sheet.iter_rows(): # 判断是否所有单元格值都为空 if not all(cell.value is not None for cell in row): sheet.delete_rows(row[0].row, 1) # 递归处理删除行后的表格 remove_empty_rows(sheet) return wb = openpyxl.load_workbook(path) sheet = wb['Sheet1'] remove_empty_rows(sheet) wb.save(path) #----------------------------------------------------------------------------------------------------------------------------------- print("-" * 20) # 为A列设置列名"Loc" wb = openpyxl.load_workbook(path) ws = wb['Sheet1'] ws['A1'] = 'Loc' print('空列(A1)已命名为: ' + ws['A1'].value) wb.save(path) #----------------------------------------------------------------------------------------------------------------------------------- # 设置列宽 def format_col_width(ws): cols = ['A','B','C','D','E','F','G','H','I','J','K','L','M'] for col in cols: ws.column_dimensions[col].width = 20 wb = openpyxl.load_workbook(path) ws = wb['Sheet1'] format_col_width(ws) wb.save(path) print("-" * 20) #----------------------------------------------------------------------------------------------------------------------------------- print('移除空行(Bravo阶段)') wb = openpyxl.load_workbook(path) sheet = wb['Sheet1'] # 重新调用移除空行函数 remove_empty_rows(sheet) wb.save(path) #----------------------------------------------------------------------------------------------------------------------------------- print("-" * 20) print('移除合计行') # 关键步骤:用pandas读取处理后的文件为DataFrame,删除Loc列以Totals开头的行 df = pd.read_excel(path) # 过滤掉Loc列以Totals开头的行 df = df[~df['Loc'].astype(str).str.contains('^Totals')] # 将处理后的DataFrame保存回文件 df.to_excel(path, index=False, header=True) #----------------------------------------------------------------------------------------------------------------------------------- print("-" * 20) # 统计最终行列数 wb_obj = openpyxl.load_workbook(path) sheet_obj = wb_obj.active print('Bravo清理后行数: ', sheet_obj.max_row) print('Bravo清理后列数: ', sheet_obj.max_column) max_col = sheet_obj.max_column #----------------------------------------------------------------------------------------------------------------------------------- print("-" * 20) print('最终列名:') for i in range(1, max_col + 1): cell_obj = sheet_obj.cell(row = 1, column = i) print(cell_obj.value) wb.save(path) print("-" * 20) print('程序结束') #-----------------------------------------------------------------------------------------------------------------------------------
关键修改说明
- 修复类型错误:在移除合计行的步骤中,先通过
pd.read_excel(path)将文件读取为DataFrame对象,再执行过滤逻辑,避免对字符串路径使用列索引。 - 修正匹配规则:根据需求将正则匹配改为
^Totals,确保删除以"Totals"开头的合计行。 - 优化空行移除逻辑:将原递归函数封装为
remove_empty_rows,并在两个阶段正确调用执行。 - 修复列宽设置:原脚本定义了列宽函数但未调用,现在补充调用逻辑确保列宽生效。
- 修复保存错误:修正原脚本中
wb.save('wb')的错误写法,改为保存到指定路径。
内容的提问来源于stack exchange,提问作者jarodmwk
相关产品推荐
相关产品推荐

