如何在Python Pandas中同时提取文本与数值并导出至Excel?
解决Pandas提取PDF数据时文本与数值格式区分的问题
问题描述
我是Python Pandas新手,现有代码可从PDF文件提取指定数据并导出至Excel文件,代码运行正常,但所有数据均以文本格式导出。请问能否在同一代码中实现文本与数值的分别提取?我曾尝试使用
str.extract(r"([A-Za-z\s]+)([\d-]+)")但未成功,附上现有代码寻求帮助:
import os import pandas as pd import numpy as np import glob import pdfplumber def get_keyword(start, end, text): for i in range(len(start)): try: field = ((text.split(start[i]))[1].split(end[i])[0]) return field except: continue def main(): my_dataframe = pd.DataFrame() for files in glob.glob("C:/PDFs\\*.pdf"): with pdfplumber.open(files) as pdf: page = pdf.pages[0] text = page.extract_text() text = " ".join(text.split()) # obtain keyword #1-Find Supplier-This is text & it is fine start = ['SUPPLIER '] end = [' Purchase'] keyword1 = get_keyword(start, end, text) # obtain keyword #2-Find Invoice, This is number-which need to number not text. start = ['Invoice Weight(Kg) '] end = ['.00 Net Weight.(Kg)'] keyword2 = get_keyword(start, end, text) my_list = [keyword1, keyword2] my_list = pd.Series(my_list) my_dataframe = my_dataframe.append(my_list, ignore_index=True) print("Document's keywords have been extracted successfully!") my_dataframe = my_dataframe.rename(columns={0:'Supplier', 1:'Invoice Number', 2:'Mill Lot Number'}) save_path: str = 'C:/PDFs' os.chdir(save_path) # extract my dataframe to an .xlsx file! my_dataframe.to_excel('sample.xlsx', sheet_name = 'Sheet1') print("") print(my_dataframe) if __name__ == '__main__': main()
解决方案
核心需求是将提取到的数值型数据转为数值格式(而非文本),以下是具体修改方案:
1. 针对数值字段做类型转换
提取到数值类字段后,直接尝试将其转为浮点型(或整型),转换失败时设为缺失值,保证数据格式统一:
# 处理Invoice Weight的数值转换 try: keyword2 = float(keyword2) except ValueError: keyword2 = np.nan # 提取内容非数值时设为缺失值
2. 优化代码效率(可选)
- 原代码在循环内重复保存Excel文件,改为所有文件处理完成后统一保存,减少IO操作
DataFrame.append已被标记为弃用,改用pd.concat或列表存储数据后统一转DataFrame,更符合Pandas新版本规范
完整修改后的代码
import os import pandas as pd import numpy as np import glob import pdfplumber def get_keyword(start, end, text): for i in range(len(start)): try: field = ((text.split(start[i]))[1].split(end[i])[0]) return field.strip() # 新增:去除前后空白字符,避免干扰类型转换 except: continue def main(): # 用列表存储所有提取结果,最后统一转为DataFrame data_list = [] for files in glob.glob("C:/PDFs\\*.pdf"): with pdfplumber.open(files) as pdf: page = pdf.pages[0] text = page.extract_text() text = " ".join(text.split()) # 提取供应商(文本型) start = ['SUPPLIER '] end = [' Purchase'] keyword1 = get_keyword(start, end, text) # 提取发票重量(数值型) start = ['Invoice Weight(Kg) '] end = ['.00 Net Weight.(Kg)'] keyword2 = get_keyword(start, end, text) # 类型转换 try: keyword2 = float(keyword2) except (ValueError, TypeError): keyword2 = np.nan # 将单条数据加入列表 data_list.append({'Supplier': keyword1, 'Invoice Weight(Kg)': keyword2}) print(f"已成功提取文件:{os.path.basename(files)}") # 统一转为DataFrame my_dataframe = pd.DataFrame(data_list) # 保存Excel save_path = 'C:/PDFs' os.chdir(save_path) my_dataframe.to_excel('sample.xlsx', sheet_name='Sheet1', index=False) print("\n提取结果:") print(my_dataframe) if __name__ == '__main__': main()
关于str.extract失败的说明
你之前尝试的str.extract是Pandas Series的正则提取方法,需要先将目标文本转为Series再使用,但针对你当前通过字符串分割提取字段的场景,直接对提取结果做类型转换更直接,无需复杂正则。
内容的提问来源于stack exchange,提问作者Ajit Kumar Jena
相关产品推荐
相关产品推荐

