Python案例如何用Pandas做数据正则提取

wen python案例 2

本文目录导读:

Python案例如何用Pandas做数据正则提取

  1. 基础准备
  2. 使用 str.extract() 提取单个字段
  3. 使用 str.extractall() 提取多个匹配
  4. 使用 str.contains() 进行条件筛选
  5. 使用 str.replace() 进行替换操作
  6. 实战案例:数据分析清洗
  7. 高级应用:多条件正则匹配
  8. 批量处理和数据验证
  9. 使用命名捕获组
  10. 性能优化技巧

我来详细介绍如何使用Pandas进行数据正则提取,包含多个实用案例。

基础准备

import pandas as pd
import re
# 创建示例数据
data = {
    'text': [
        '联系方式:138-1234-5678,邮箱:user1@example.com',
        '电话:010-87654321,邮箱:test@email.com',
        '手机:159-1234-5678,QQ:123456789',
        '地址:北京市朝阳区XXX路,电话:13900000000'
    ]
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)

使用 str.extract() 提取单个字段

# 提取手机号(11位数字)
df['phone'] = df['text'].str.extract(r'(\d{3}-\d{4}-\d{4})')
print("提取手机号:")
print(df[['text', 'phone']].head())

使用 str.extractall() 提取多个匹配

# 提取所有数字信息
patterns = {
    'phone': r'(\d{3}-\d{4}-\d{4})',
    'email': r'([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})',
    'qq': r'(\d{5,10})'
}
# 提取所有匹配
df_extracted = df['text'].str.extractall('|'.join([f'(?P<{k}>{v})' for k, v in patterns.items()]))
print("所有提取结果:")
print(df_extracted)

使用 str.contains() 进行条件筛选

# 筛选包含邮箱的行
has_email = df['text'].str.contains(r'@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}', na=False)
print("包含邮箱的记录:")
print(df[has_email])

使用 str.replace() 进行替换操作

# 隐藏手机号中间4位
df['masked_phone'] = df['text'].str.replace(
    r'(\d{3})-(\d{4})-(\d{4})',
    r'\1-****-\3',
    regex=True
)
print("隐藏手机号:")
print(df[['text', 'masked_phone']].head())

实战案例:数据分析清洗

# 创建更复杂的数据集
data_complex = {
    'user_info': [
        '张三|13812345678|beijing|25岁|男',
        '李四|13901234567|shanghai|30岁|女',
        '王五|15811223344|广东深圳|28岁|男',
        '赵六|无|unknown|22岁|女'
    ],
    'order_id': ['ORD2023001', 'ORD2023002', 'ORD2023003', 'ORD2023004']
}
df_complex = pd.DataFrame(data_complex)
# 提取姓名、手机号、城市
pattern = r'^(.*?)\|(.*?)\|(.*?)\|'
df_complex[['name', 'phone', 'city']] = df_complex['user_info'].str.extract(pattern)
print("提取后的数据:")
print(df_complex[['order_id', 'name', 'phone', 'city']].head())

高级应用:多条件正则匹配

# 处理不同格式的电话号码
phone_data = {
    'contact': [
        '手机:138-1234-5678',
        '电话:010-87654321',
        '座机:0755-88886666',
        '国际:+86 13812345678'
    ]
}
df_phone = pd.DataFrame(phone_data)
# 提取不同格式的电话号码
def extract_phone(text):
    patterns = [
        r'(\d{3}-\d{4}-\d{4})',  # 手机号格式
        r'(\d{3,4}-\d{7,8})',    # 座机格式
        r'(\+\d{1,3}\s?\d{10,11})'  # 国际格式
    ]
    for pattern in patterns:
        match = re.search(pattern, text)
        if match:
            return match.group(1)
    return None
df_phone['extracted_phone'] = df_phone['contact'].apply(extract_phone)
print("电话号码提取结果:")
print(df_phone)

批量处理和数据验证

# 数据验证函数
def validate_email(email):
    """验证邮箱格式"""
    pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
    return bool(re.match(pattern, str(email)))
def validate_phone(phone):
    """验证手机号格式"""
    pattern = r'^\d{3}-\d{4}-\d{4}$'
    return bool(re.match(pattern, str(phone)))
# 创建验证列
df['email_valid'] = df['text'].str.extract(r'([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})')[0].apply(
    lambda x: validate_email(x) if pd.notna(x) else False
)
print("邮箱验证结果:")
print(df[['text', 'email_valid']].head())

使用命名捕获组

# 提取结构化信息
s = pd.Series([
    "李明,30岁,北京",
    "张华,25岁,上海",
    "王芳,28岁,广州"
])
# 使用命名捕获组
df_names = s.str.extract(r'(?P<name>\w+),(?P<age>\d+)岁,(?P<city>\w+)')
print("命名捕获组提取结果:")
print(df_names)

性能优化技巧

import time
# 大数据集模拟
big_data = pd.DataFrame({
    'text': ['测试数据' + str(i) + ',电话:138-1234-5678' for i in range(10000)]
})
# 方法1:使用向量化操作
start = time.time()
result1 = big_data['text'].str.extract(r'(\d{3}-\d{4}-\d{4})')
print(f"向量化操作耗时:{time.time() - start:.3f}秒")
# 方法2:使用apply方法
start = time.time()
result2 = big_data['text'].apply(lambda x: re.search(r'(\d{3}-\d{4}-\d{4})', x).group(1) if re.search(r'(\d{3}-\d{4}-\d{4})', x) else None)
print(f"apply方法耗时:{time.time() - start:.3f}秒")

使用Pandas进行正则提取的主要优势:

  1. 向量化操作:比循环处理快很多
  2. 链式调用str.extract(), str.contains()等可以组合使用
  3. 灵活性强:支持复杂的正则表达式
  4. 易于数据清洗:方便处理缺失值和异常数据

常见应用场景:

  • 数据清洗(提取电话号码、邮箱、身份证号等)
  • 文本分类(基于关键词或模式)
  • 数据验证(格式检查)
  • 信息抽取(从非结构化文本中提取结构化数据)

记住在使用正则时要注意:

  • 使用原始字符串(r'')避免转义问题
  • 考虑边界情况和异常值
  • 大数据集时优先使用向量化操作

抱歉,评论功能暂时关闭!