如何将pdfplumber extract_table()输出正确格式化为DataFrame?
问题
已通过pdfplumber提取无水平线PDF表格,接近成功但无法将提取的数据转换为可用于DataFrame的格式。目标表格包含12条商品数据(含编号、名称、数量、单价、税率、金额等字段),需排除底部从“Samtals ISK...”开始的总计部分。
当前使用代码:
# Extract text and table from pdf. with pdfplumber.open(file_path) as invoice: page = invoice.pages[0] text = page.extract_text().split('\n') table = page.extract_table(table_settings={"vertical_strategy": "text", "horizontal_strategy": "lines"}) table
当前输出的table将每列的多行数据合并为带换行符的字符串,无法直接生成每行对应一条商品的DataFrame,输出示例:
[['', '7159\n7156\n7154\n7155\n7158\n7157\n7160\n5013\n5014\n5015\n5025\n5017', 'Hummus\nGuacamole\nChili Mayo\nSalsa\nTzatzikisósa\nPestó\nGarlic oil\nSætkartöflusalat\nRauðrófur\nBrokkolísalat\nBrokkoli\nSalat', 'Samtal\n11% VS\nSamtal', '1\n1\n2\n1\n1\n1\n1\n5\n6\n1\n2\n1\ns \nK\ns', '0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n8\nISK\nISK', 'án VS\n með', '809,00\n2.170,00\n444,00\n812,00\n713,00\n909,00\n1.886,00\n1.205,00\n1.683,00\n1.391,00\n1.362,00\n1.980,00\nK\nVSK', '11\n11\n11\n11\n11\n11\n11\n11\n11\n11\n11\n11', '8.090\n21.700\n8.880\n8.120\n7.130\n9.090\n18.860\n60.250\n100.980\n13.910\n27.240\n35.640\n319.890\n35.188'], [None, None, None, None, None, None, None, None, None, '355.078']]
需解决:将合并的列数据拆分,生成每行对应一条商品的结构化数据,用于DataFrame。
解决方案
无需更换提取方式,只需对现有提取结果做格式化处理即可,步骤如下:
1. 提取核心数据块
先取出包含商品数据的第一行(排除总计行):
import pandas as pd # 取出商品数据行,排除总计行 data_row = table[0]
2. 拆分并清理每列数据
对每个列的字符串按\n拆分,过滤掉无关的冗余文本,只保留12条商品对应的数据:
# 拆分商品编号:直接取前12个(对应12条商品) item_codes = data_row[1].split('\n')[:12] # 拆分商品名称:直接取前12个 item_names = data_row[2].split('\n')[:12] # 拆分数量:过滤掉"s"、"K"这类冗余文本,取前12个数字 quantities = [x for x in data_row[4].split('\n') if x.strip().isdigit()][:12] # 拆分单价:过滤掉"K"、"VSK",取前12个含逗号的金额值 unit_prices = [x for x in data_row[7].split('\n') if ',' in x][:12] # 拆分税率:直接取前12个 tax_rates = data_row[8].split('\n')[:12] # 拆分金额:取前12个(排除后续的小计、总计值) amounts = data_row[9].split('\n')[:12]
3. 组装为DataFrame
将清理后的列表组合成字典,转换为标准DataFrame:
# 组装结构化数据 structured_data = { "商品编号": item_codes, "商品名称": item_names, "数量": quantities, "单价": unit_prices, "税率(%)": tax_rates, "金额": amounts } # 转换为DataFrame df = pd.DataFrame(structured_data) print(df)
代码说明
- 通过特征判断(比如金额含逗号、数量为数字)过滤冗余文本,确保只保留商品行数据
- 取前12个元素是匹配目标表格的商品数量,可根据实际表格行数调整
- 最终生成的DataFrame每行对应一条商品数据,可直接用于后续分析或导出
内容的提问来源于stack exchange,提问作者GT1992
相关产品推荐
相关产品推荐

