如何在Python中从CSV/Excel提取多表生成独立DataFrame
从CSV/Excel提取多表格并转为独立DataFrame的实现方案
可以通过识别表格分隔标记+逐段提取数据的方式实现,核心思路是先定位每个表格的边界,再提取B列及以后的内容转为DataFrame。以下是针对CSV和Excel文件的具体实现:
一、处理CSV文件
先读取所有行并过滤空行,再通过表格标题(如ABC/XYZ)识别每个表格的起始位置,提取对应列和数据:
import pandas as pd import csv def extract_csv_tables(csv_path): tables = [] # 读取所有行,过滤全空行 with open(csv_path, 'r', newline='', encoding='utf-8') as f: reader = csv.reader(f) lines = [line for line in reader if any(cell.strip() for cell in line)] i = 0 while i < len(lines): # 匹配表格标题行(第一列非空、非TITLE开头、非数字) if lines[i][0].strip() and not lines[i][0].startswith('TITLE') and not lines[i][0].strip().isdigit(): table_name = lines[i][0].strip() i += 1 # 跳过带"X"的行 while i < len(lines) and (not lines[i][0].strip() or lines[i][-1].strip() == 'X'): i += 1 if i >= len(lines): break # 提取B列开始的列名 header = [cell.strip() for cell in lines[i][1:] if cell.strip()] i += 1 # 收集数据行,直到下一个表格标题 data = [] while i < len(lines): current_line = lines[i] # 判断是否进入下一个表格 if current_line[0].strip() and not current_line[0].startswith('TITLE') and not current_line[0].strip().isdigit(): break # 提取B列到对应列数的内容 row = [cell.strip() for cell in current_line[1:len(header)+1]] if row: data.append(row) i += 1 # 转为DataFrame并添加到列表 df = pd.DataFrame(data, columns=header) df.rename(columns={header[0]: 'TITLE'}, inplace=True) tables.append((table_name, df)) else: i += 1 return tables # 使用示例 for table_title, df in extract_csv_tables("your_data.csv"): print(f"=== {table_title} ===") print(df)
二、处理Excel文件
用openpyxl读取工作表内容,逻辑和CSV处理一致,适配Excel的行读取方式:
import pandas as pd from openpyxl import load_workbook def extract_excel_tables(excel_path, sheet_name="Sheet1"): tables = [] wb = load_workbook(excel_path, data_only=True) ws = wb[sheet_name] # 读取所有行,过滤全空行并转为字符串列表 lines = [] for row in ws.iter_rows(values_only=True): if any(cell and str(cell).strip() for cell in row): lines.append([str(cell).strip() if cell else "" for cell in row]) i = 0 while i < len(lines): if lines[i][0] and not lines[i][0].startswith('TITLE') and not lines[i][0].isdigit(): table_name = lines[i][0] i += 1 # 跳过带"X"的行 while i < len(lines) and (not lines[i][0] or lines[i][-1] == 'X'): i += 1 if i >= len(lines): break # 提取列名 header = [cell for cell in lines[i][1:] if cell] i += 1 # 收集数据行 data = [] while i < len(lines): current_line = lines[i] if current_line[0] and not current_line[0].startswith('TITLE') and not current_line[0].isdigit(): break row = [current_line[j] for j in range(1, len(header)+1)] if any(row): data.append(row) i += 1 df = pd.DataFrame(data, columns=header) df.rename(columns={header[0]: 'TITLE'}, inplace=True) tables.append((table_name, df)) else: i += 1 return tables # 使用示例 for table_title, df in extract_excel_tables("your_data.xlsx"): print(f"=== {table_title} ===") print(df)
关键说明
- 代码默认表格以空行分隔,表格标题是每行第一列非空、不以
TITLE开头、非数字的行 - 自动适配不同列数的表格(如示例中3列年份+1汇总列、5列年份+1汇总列)
- 如果你的表格结构有细微差异,可调整标题匹配、空行判断的逻辑
内容的提问来源于stack exchange,提问作者ImNotSureAboutStats
相关产品推荐
相关产品推荐

