如何根据特定条件生成章节ID
我有一个 pandas 数据框,里面有这样的输入:
data = {
'sec_id': ['1', '', '1.2', '1.3', '1.3.1', '1.3.2', '2', '2.1', '2.2', '2.3', '', '2.3.2', '2.3.3', '3', '4', '4.1', '4.1.1', '4.2', '4.3', '4.4', '5', '5.1', '5.2', '5.3', '5.3.1', '5.3.2', '5.3.3', '5.3.4', '5.3.5', '5.4', '5.5', '6', '6.1', '6.1.1', '6.2', '6.3', '6.4', '6.5', '6.6', '6.6.1', '6.6.2', '6.6.3', '6.7', '6.8', '6.9', '6.9.1', '', '', '6.9.2'],
'p_type': ['Heading1', 'Heading2', 'Heading2', 'Heading2', 'Heading3', 'Heading3', 'Heading1', 'Heading2', 'Heading2', 'Heading2', 'Heading3', 'Heading3', 'Heading3', 'Heading1', 'Heading1', 'Heading2', 'Heading3', 'Heading2', 'Heading2', 'Heading2', 'Heading1', 'Heading2', 'Heading2', 'Heading2', 'Heading3', 'Heading3', 'Heading3', 'Heading3', 'Heading3', 'Heading2', 'Heading2', 'Heading1', 'Heading2', 'Heading3', 'Heading2', 'Heading2', 'Heading2', 'Heading2', 'Heading2', 'Heading3', 'Heading3', 'Heading3', 'Heading2', 'Heading2', 'Heading2', 'Heading3', 'Heading4', 'Heading4', 'Heading3']
}
df = pd.DataFrame(data)
现在的问题是,要把空白的 "document_section_id" 值填上正确的段落 ID,使用前面的值作为参考。
条件:
数字的位数由 "paragraph type" 列决定。例如,对于 "Heading3",应该有 4 位数字和 3 个点,格式是:1.2.3.1。
对于每个空值,它应该参考前面可用的 "paragraph type",并相应地加 1。 例子 1:根据输入,第 12 行的段落 ID 可以从前一行得出,计算结果是 2.3.1。例子 2:对于第 48 和 49 行,段落 ID 需要分别得出为 6.9.1.1 和 6.9.1.2。
最多可以有 10 级子段,所以这一点也要考虑到,无论子段的数量是多少。
输出:
sec_id = [
'1', '1.1', '1.2', '1.3', '1.3.1', '1.3.2', '2', '2.1', '2.2', '2.3',
'2.3.1', '2.3.2', '2.3.3', '3', '4', '4.1', '4.1.1', '4.2', '4.3',
'4.4', '5', '5.1', '5.2', '5.3', '5.3.1', '5.3.2', '5.3.3', '5.3.4',
'5.3.5', '5.4', '5.5', '6', '6.1', '6.1.1', '6.2', '6.3', '6.4',
'6.5', '6.6', '6.6.1', '6.6.2', '6.6.3', '6.7', '6.8', '6.9', '6.9.1',
'6.9.1.1', '6.9.1.2', '6.9.2'
]
p_type = [
'Heading1', 'Heading2', 'Heading2', 'Heading2', 'Heading3', 'Heading3',
'Heading1', 'Heading2', 'Heading2', 'Heading2', 'Heading3', 'Heading3',
'Heading3', 'Heading1', 'Heading1', 'Heading2', 'Heading3', 'Heading2',
'Heading2', 'Heading2', 'Heading1', 'Heading2', 'Heading2', 'Heading2',
'Heading3', 'Heading3', 'Heading3', 'Heading3', 'Heading3', 'Heading2',
'Heading2', 'Heading1', 'Heading2', 'Heading3', 'Heading2', 'Heading2',
'Heading2', 'Heading2', 'Heading2', 'Heading3', 'Heading3', 'Heading3',
'Heading3', 'Heading2', 'Heading2', 'Heading2', 'Heading3', 'Heading4',
'Heading4', 'Heading3'
]
这是我尝试的代码,但输出结果不准确:
current_section_id = ""
current_level = 0
for index, row in df.iterrows():
if row['sec_id'] == '':
current_level += 1
section_id = current_section_id.split('.')
section_id[current_level - 1] = str(int(section_id[current_level - 1]) + 1)
section_id = '.'.join(section_id[:current_level])
current_section_id = section_id
df.at[index, 'document_section_id'] = section_id
else:
current_section_id = row['sec_id']
current_level = row['paragraph_type'].count('Heading') - 1
1 个回答
2
我觉得在Pandas里不需要这样做。你可以创建一个类,这个类可以跟踪当前的段落,并根据段落的类型来增加1,或者添加一个子段落,或者截断并增加。
这里有个例子:
class SectionCreator:
def __init__(self):
self.section = [0]
def __call__(self, paragraph_type: str):
depth = int(paragraph_type.replace('Heading', ''))
section = self.section[:depth]
if depth == len(section) + 1:
section.append(1)
elif depth > len(section) + 1:
raise ValueError(f'Heading depth increased from {len(section)} to {depth}')
else:
section[depth - 1] += 1
self.section = section
return '.'.join(map(str, self.section))
使用的时候,先创建这个对象,然后一次传入一个段落类型。
headings = ['Heading1', 'Heading2', 'Heading2', 'Heading2', 'Heading3',
'Heading3', 'Heading1', 'Heading2', 'Heading2', 'Heading2', 'Heading3',
'Heading3', 'Heading3', 'Heading1', 'Heading1', 'Heading2', 'Heading3',
'Heading2', 'Heading2', 'Heading2', 'Heading1', 'Heading2', 'Heading2',
'Heading2', 'Heading3', 'Heading3', 'Heading3', 'Heading3', 'Heading3',
'Heading2', 'Heading2', 'Heading1', 'Heading2', 'Heading3', 'Heading2',
'Heading2', 'Heading2', 'Heading2', 'Heading2', 'Heading3', 'Heading3',
'Heading3', 'Heading2', 'Heading2', 'Heading2', 'Heading3', 'Heading4',
'Heading4', 'Heading3']
sc = SectionCreator()
for h in headings:
print(sc(h))
打印出来的结果是:
1
1.1
1.2
1.3
1.3.1
1.3.2
2
2.1
2.2
2.3
2.3.1
2.3.2
2.3.3
3
4
4.1
4.1.1
4.2
4.3
4.4
5
5.1
5.2
5.3
5.3.1
5.3.2
5.3.3
5.3.4
5.3.5
5.4
5.5
6
6.1
6.1.1
6.2
6.3
6.4
6.5
6.6
6.6.1
6.6.2
6.6.3
6.7
6.8
6.9
6.9.1
6.9.1.1
6.9.1.2
6.9.2
我添加了一个例外情况,就是当段落类型的深度跳跃超过1级时,会抛出一个异常。所以从2跳到4会引发异常。
sc = SectionCreator()
sc('Heading1') # -> "1"
sc('Heading2') # -> "1.1"
sc('Heading4')
# raises:
ValueError: Heading depth increased from 2 to 4