表格填补是RAG分块中常见的需求,但不同格式的表格处理方式有所不同。本文将对 Markdown、HTML、Excel 的合并单元格进行说明,并给出 Python 示例,演示如何解析和填补。
1. Markdown 表格
Markdown 只能用空值表示合并单元格。(只有列方向的合并表格)
示例
| 姓名 | 科目 | 分数 |
|------|------|------|
| 张三 | 数学 | 90 |
| | 语文 | 85 |
| 张三 | 英语 | 88 |
| 李四 | 数学 | 92 |
| | 语文 | 80 |
Python 解析
python
import pandas as pd
from io import StringIO
markdown_table = """
姓名|科目|分数
张三|数学|90
|语文|85
张三|英语|88
李四|数学|92
|语文|80
"""
df = pd.read_csv(StringIO(markdown_table), sep="|")
df['姓名'] = df['姓名'].ffill()
print(df)
输出
姓名 科目 分数
0 张三 数学 90
1 张三 语文 85
2 张三 英语 88
3 李四 数学 92
4 李四 语文 80
2. HTML 表格
HTML 可以用 rowspan
和 colspan进行填补
。
示例
<table>
<tr>
<td rowspan="2">张三</td>
<td>数学</td>
<td>90</td>
</tr>
<tr>
<td>语文</td>
<td>85</td>
</tr>
<tr>
<td rowspan="2">李四</td>
<td>数学</td>
<td>92</td>
</tr>
<tr>
<td>语文</td>
<td>80</td>
</tr>
</table>
Python 解析(BeautifulSoup + 填补 rowspan)
python
from bs4 import BeautifulSoup
html = """
<table>
<tr>
<td rowspan="2">张三</td>
<td>数学</td>
<td>90</td>
</tr>
<tr>
<td>语文</td>
<td>85</td>
</tr>
<tr>
<td rowspan="2">李四</td>
<td>数学</td>
<td>92</td>
</tr>
<tr>
<td>语文</td>
<td>80</td>
</tr>
</table>
"""
soup = BeautifulSoup(html, "html.parser")
rows = soup.find_all("tr")
# 构建空表格
table = []
for r, row in enumerate(rows):
cols = row.find_all("td")
current_row = []
for col in cols:
value = col.get_text()
rowspan = int(col.get("rowspan", 1))
colspan = int(col.get("colspan", 1))
current_row.append({"value": value, "rowspan": rowspan, "colspan": colspan})
table.append(current_row)
# 计算总列数
max_cols = max(sum(cell["colspan"] for cell in row) for row in table)
# 初始化填补后的表格
filled_table = [[None]*max_cols for _ in range(len(table))]
# 填充逻辑
for r, row in enumerate(table):
c_idx = 0
for cell in row:
# 找到当前行可用位置
while filled_table[r][c_idx] is not None:
c_idx += 1
# 填充 rowspan 和 colspan
for i in range(cell["rowspan"]):
for j in range(cell["colspan"]):
filled_table[r+i][c_idx+j] = cell["value"]
c_idx += cell["colspan"]
# 打印结果
for r in filled_table:
print(r)
输出
['张三', '数学', '90']
['张三', '语文', '85']
['李四', '数学', '92']
['李四', '语文', '80']
3. Excel 表格
Excel 合并单元格读取后用 pandas 填补即可。
姓名 | 科目 | 分数 |
---|---|---|
张三 (合并两行) | 数学 | 90 |
语文 | 85 | |
李四 (合并两行) | 数学 | 92 |
语文 | 80 |
import pandas as pd
df = pd.read_excel("example.xlsx")
df['姓名'] = df['姓名'].ffill()
print(df)
输出
姓名 科目 分数
0 张三 数学 90
1 张三 语文 85
2 李四 数学 92
3 李四 语文 80
4. Word 表格合并单元格特点
在 Word 文档里,表格同样支持"合并单元格",类似于 Excel,但它有自己的特点:
-
可以 合并行(rowspan) 或 合并列(colspan)
-
合并单元格的内容只保留左上角的单元格,其余单元格为空
-
Python 读取 Word 表格通常用
python-docx
库 -
读取后的表格数据需要手动填补合并单元格的空值,类似 Excel
示例 Word 表格
姓名 | 科目 | 分数 |
---|---|---|
张三 (合并两行) | 数学 | 90 |
语文 | 85 | |
李四 (合并两行) | 数学 | 92 |
语文 | 80 |
Python 解析 Word 表格并填补
python
from docx import Document
doc = Document("example.docx")
table = doc.tables[0]
# 先读取表格内容
data = []
for row in table.rows:
data.append([cell.text.strip() if cell.text.strip() else None for cell in row.cells])
# 填补合并单元格(垂直填充)
for col in range(len(data[0])):
last_val = None
for row in data:
if row[col]:
last_val = row[col]
else:
row[col] = last_val
for row in data:
print(row)
输出
['张三', '数学', '90']
['张三', '语文', '85']
['李四', '数学', '92']
['李四', '语文', '80']
结论:
-
Markdown:用空值表示合并单元格,再
ffill()
-
HTML:用
rowspan
,需要逻辑填补 -
Excel:合并单元格读取后是 NaN,用
ffill()
-
Word 表格合并单元格读取后非首单元格为
None
-
可以用 逐列垂直填充 (类似 Excel
ffill()
) -
Python 最常用库是
python-docx