如何将docx非结构化复杂文本解析为目标结构的pandas DataFrame?
从非结构化docx提取数据生成指定DataFrame
问题描述
我有一个包含以下非结构化文本的docx文件:
docx File Prep 1. Northern Kitchen Number One K01-24-01-P01 $132,500 Background: - None Project Description: - Some long project description List of Deliverables: - #1 - A deliverable. - #2 - Another deliverable. Others: - None Cost: - Prep Item #1 & 2 - Some text here. Criteria: - #1a, 1b, & 2c - Stuff here. - #2 - More stuff here. - #3 - Even more stuff here too. 2. Southern Kitchen Number Two K03-24-01-P01 $50,2333 Background: - None Project Description: - None List of Deliverables: - #1 - A deliverable. Others: - None Cost: - None Criteria: - #1a, 1b, & 2c - Stuff here.
需要提取所有不含“None”的行,生成如下结构的DataFrame:
| Kitchen | Process | Code | Task | Description |
|---|---|---|---|---|
| Northern Kitchen Number One | Prep | K01-24-01-P01 | Project Description | Some long project description. |
| Northern Kitchen Number One | Prep | K01-24-01-P01 | List of Deliverables | #1 - A deliverable. |
| Northern Kitchen Number One | Prep | K01-24-01-P01 | List of Deliverables | #2 - Another deliverable. |
| Northern Kitchen Number One | Prep | K01-24-01-P01 | Cost | Prep Item #1 & 2 - Some text here. |
| Northern Kitchen Number One | Prep | K01-24-01-P01 | Criteria | #1a, 1b, & 2c - Stuff here. |
| Northern Kitchen Number One | Prep | K01-24-01-P01 | Criteria | #2 - More stuff here. |
| Northern Kitchen Number One | Prep | K01-24-01-P01 | Criteria | #3 - Even more stuff here too. |
| Southern Kitchen Number Two | Prep | K03-24-01-P01 | List of Deliverables | #1 - A deliverable. |
| Southern Kitchen Number Two | Prep | K03-24-01-P01 | Criteria | #1a, 1b, & 2c - Stuff here. |
目前我仅能提取文档中的行并保存为CSV文件,但无法整理成目标DataFrame结构。现有代码如下:
import docx import io import pandas as pd stuff = '\n'.join([p.text for p in docx.Document(path).paragraphs]) df = pd.read_csv(io.StringIO(stuff), on_bad_lines='skip') df.to_excel('stuff.csv')
需要借助正则表达式和字典实现目标结构的DataFrame生成。
解决方案
实现思路
- 读取docx文档的所有段落文本,过滤掉空行;
- 提取Process(此处为"Prep");
- 使用正则表达式匹配厨房条目行,提取Kitchen名称、Code;
- 遍历剩余段落,跟踪当前任务类型(如Project Description、List of Deliverables等),收集非"None"的描述内容;
- 将收集到的所有有效数据组装成字典列表,最后转换为DataFrame。
代码实现
import docx import re import pandas as pd def extract_kitchen_data(path): # 读取docx文档段落,过滤空行 doc = docx.Document(path) paragraphs = [p.strip() for p in [para.text for para in doc.paragraphs] if p.strip()] # 初始化变量 process = None current_kitchen = None current_code = None current_task = None data = [] # 匹配厨房条目的正则:匹配类似"1. Northern Kitchen Number One K01-24-01-P01 $132,500"的行 kitchen_pattern = re.compile(r'^\d+\.\s+(.*?)\s+([A-Z0-9-]+)\s+\$[\d,]+$') for line in paragraphs: # 提取Process if not process and line == 'Prep': process = line continue # 匹配厨房条目 kitchen_match = kitchen_pattern.match(line) if kitchen_match: current_kitchen = kitchen_match.group(1).strip() current_code = kitchen_match.group(2).strip() continue # 识别任务类型行(以":"结尾的行) if line.endswith(':'): current_task = line[:-1].strip() continue # 处理列表项(以"- "开头的行) if line.startswith('- '): desc = line[2:].strip() # 跳过包含"None"的内容 if desc == 'None': continue # 收集有效数据 data.append({ 'Kitchen': current_kitchen, 'Process': process, 'Code': current_code, 'Task': current_task, 'Description': desc }) # 转换为DataFrame df = pd.DataFrame(data) return df # 使用示例 path = 'your_document.docx' # 替换为你的docx文件路径 result_df = extract_kitchen_data(path) # 查看结果 print(result_df) # 保存为Excel result_df.to_excel('kitchen_data.xlsx', index=False)
代码说明
- 正则匹配厨房条目:通过
^\d+\.\s+(.*?)\s+([A-Z0-9-]+)\s+\$[\d,]+$精准匹配厨房行,提取名称和编码; - 任务类型跟踪:遇到以":"结尾的行时,记录当前对应的任务分类;
- 数据过滤与收集:跳过描述为"None"的无效行,将有效数据存入字典列表;
- DataFrame生成:将字典列表转换为指定结构的DataFrame,可直接保存为Excel文件。
内容的提问来源于stack exchange,提问作者Noa Mao
相关产品推荐
相关产品推荐

