发布于2026-07-20 阅读(0)
扫一扫,手机访问
本文介绍一种基于正则匹配与上下文记忆的稳健方法,用于从 section_name 中提取结构化章节 ID(如 1.1、1.3.1),并将其填充至 section_id 列;对无编号条目(如 Synopsis)自动关联最近匹配的编号,空值保持不变。
在处理结构化文档类数据——比如测试用例、标准规范,或者从PDF表格里解析出来的结果——时,经常会遇到一个头疼的问题:数据框里的 `section_name` 列,既包含了带编号的标题(比如 "1.2.Schema12"),也混着纯内容标题(比如 "Synopsis")。目标很明确:为每一行数据准确推断出它所属的逻辑章节ID,然后填到新列 `section_id` 里。这可不是简单的字符串切分,背后其实是上下文语义映射的活儿。
先说核心思路,其实就两步:
下面是一段可以直接运行的完整代码,已经处理了空值、None和空白字符串这些边界情况:
import pandas as pd
import numpy as np
import re
# 构造示例数据(含空值与 None)
data = {
'section_name': [
'1.Test Summary9',
'1.1.Synopsis9',
'1.2.Schema12',
'1.3.1.Test Period I - Screening13',
'1.3.2.Period II - obes-Treatment 15',
'Synopsis',
'Test Period I - Screening',
None,
''
]
}
df = pd.DataFrame(data)
def extract_section_id(row, memo_dict):
name = row['section_name']
# 跳过 None 和纯空白
if pd.isna(name) or str(name).strip() == '':
return '' # 或返回 np.nan,按需选择
s = str(name).strip()
# 步骤1:尝试匹配编号前缀(如 1.3.1)
match = re.match(r'^(\d+(?:\.\d+)*)\.(.*)$', s)
if match:
sec_id, semantic_part = match.groups()
# 记录该语义片段对应的 ID(用于后续匹配)
memo_dict[semantic_part] = sec_id
return sec_id
else:
# 步骤2:对无编号行,在历史语义片段中查找包含关系
for semantic_key, sec_id in memo_dict.items():
if s in semantic_key or semantic_key in s:
return sec_id
return '' # 未匹配时返回空字符串
# 初始化记忆字典
section_map = {}
df['section_id'] = df.apply(lambda x: extract_section_id(x, section_map), axis=1)
print(df)
输出结果是这样的:
section_name section_id 0 1.Test Summary9 1 1 1.1.Synopsis9 1.1 2 1.2.Schema12 1.2 3 1.3.1.Test Period I - Screening13 1.3.1 4 1.3.2.Period II - obes-Treatment 15 1.3.2 5 Synopsis 1.1 6 Test Period I - Screening 1.3.1 7 None 8
这套方法有几处关键优势:
不过,有几个细节需要注意:
总的来说,这个方法在准确性、可读性和工程实用性之间找到了一个不错的平衡点,很适合用来处理各种嵌套编号文档的结构化解析任务。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8