Python 3.12 文本数据提取实战:从政府工作报告中高效抓取 100+ 数字短句

📅 2026/7/10 4:46:39 👁️ 阅读次数 📝 编程学习
Python 3.12 文本数据提取实战:从政府工作报告中高效抓取 100+ 数字短句

Python 3.12 文本数据提取实战:从政府工作报告中高效抓取 100+ 数字短句

在数据分析的日常工作中,我们经常需要从非结构化文本中提取特定模式的信息。政府工作报告、企业年报这类文档往往包含大量有价值的数据指标,但人工提取既耗时又容易出错。本文将带你用Python 3.12构建一个健壮的文本提取流水线,不仅能解决大学编程题,更能应对真实业务场景。

1. 理解任务本质与数据特点

政府工作报告这类文档有几个显著特征:中文标点丰富、数字与文字混合表述、数据指标分散。我们需要处理的不仅是简单的字符串匹配,还要考虑中文文本处理的特殊性。

典型的数字短句可能长这样:

  • "经济增长5.2%"
  • "新增就业1206万人"
  • "研发投入超过2.5万亿元"

这些短句中的数字可能是整数、小数、百分比,甚至包含单位符号。我们的解决方案需要兼容这些情况。

注意:中文全角标点与英文半角标点的处理是第一个技术难点,不正确的替换会导致后续分词异常。

2. 构建文本预处理流水线

2.1 标点符号标准化处理

首先需要建立一个完整的中文标点映射表。Python的str.maketrans()方法比循环替换更高效:

import re from collections import defaultdict # 构建中文标点转换表 chinese_punctuation = '"#$%&'()*+,-/:;<=>@[\]^_`{|}~⦅⦆「」、\u3000、〃〈〉《》「」『』【】〔〕〖〗〘〙〚〛〜〝〞〟〰〾〿–—‘’‛“”„‟…‧﹏﹑﹔·.!?。。' translator = str.maketrans({k: ' ' for k in chinese_punctuation}) def preprocess_text(text): """统一将中文标点替换为英文空格""" return text.translate(translator)

2.2 智能分词优化

简单的split()方法在中文场景下可能不够精准。我们可以结合正则表达式实现更智能的分词:

def advanced_split(text): # 处理连续空格并保留数字单位组合 return re.sub(r'\s+', ' ', text).strip().split()

3. 数字短句识别引擎

3.1 核心识别算法

判断短句是否包含数字不能简单用isdigit(),需要更复杂的模式匹配:

def contains_number(s): """判断字符串是否包含数字模式""" patterns = [ r'\d+', # 纯数字 r'\d+\.\d+', # 小数 r'\d+%', # 百分比 r'\d+\s*[万亿亿]', # 带单位 r'[一二三四五六七八九十百千万亿]+' # 中文数字 ] return any(re.search(p, s) for p in patterns)

3.2 性能优化技巧

当处理大型文档时,我们可以使用生成器表达式减少内存占用:

def extract_number_sentences(text, keyword=None): processed = preprocess_text(text) words = advanced_split(processed) if keyword == '数字短句' or (keyword and keyword.isdigit()): return (w for w in words if contains_number(w)) elif keyword: matches = [w for w in words if keyword in w] return matches if matches else None return None

4. 构建生产级解决方案

4.1 完整处理流程

将上述模块组合成可复用的数据处理类:

class ReportAnalyzer: def __init__(self, filepath): with open(filepath, 'r', encoding='utf-8') as f: self.raw_text = f.read() self.words = None def preprocess(self): cleaned = preprocess_text(self.raw_text) self.words = advanced_split(cleaned) return self def query(self, keyword): if not self.words: self.preprocess() if keyword == '数字短句': results = list(filter(contains_number, self.words)) print(*results, sep='\n') else: matches = [w for w in self.words if keyword in w] if matches: print(len(matches)) print(*matches, sep='\n') else: print('未找到关键词') return self

4.2 使用示例

analyzer = ReportAnalyzer('government_report_2024.txt') analyzer.preprocess().query('数字短句') # 提取所有数字短句 analyzer.query('就业') # 查询包含"就业"的短句

5. 高级应用与扩展

5.1 数据增强处理

提取数字后,可以进一步解析数值和单位:

def parse_number(s): # 解析数字和单位 num_match = re.search(r'(\d+\.?\d*)', s) unit_match = re.search(r'([万亿亿]元|%)', s) num = float(num_match.group(1)) if num_match else None unit = unit_match.group(0) if unit_match else '' return {'value': num, 'unit': unit, 'original': s}

5.2 结果可视化

使用Pandas可以方便地进行数据分析:

import pandas as pd def analyze_report(filepath): analyzer = ReportAnalyzer(filepath).preprocess() numbers = [parse_number(w) for w in analyzer.query('数字短句')] df = pd.DataFrame(numbers).dropna() # 按单位分组统计 print(df.groupby('unit')['value'].agg(['count', 'mean', 'max']))

6. 异常处理与边界情况

健壮的生产代码需要考虑各种边界情况:

def safe_extract(text): try: processed = preprocess_text(text) words = advanced_split(processed) return [parse_number(w) for w in words if contains_number(w)] except Exception as e: print(f"处理出错: {str(e)}") return []

在实际项目中,我发现处理政府工作报告这类文档时,最大的挑战不是技术实现,而是文本的格式一致性。不同年份的报告可能使用不同的数字表述方式,比如"5.2%"可能写作"5.2个百分点",这时候就需要不断调整正则表达式模式来适应这些变化。