本文目录导读:

- 基础准备
- 使用
str.extract()提取单个字段 - 使用
str.extractall()提取多个匹配 - 使用
str.contains()进行条件筛选 - 使用
str.replace()进行替换操作 - 实战案例:数据分析清洗
- 高级应用:多条件正则匹配
- 批量处理和数据验证
- 使用命名捕获组
- 性能优化技巧
我来详细介绍如何使用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进行正则提取的主要优势:
- 向量化操作:比循环处理快很多
- 链式调用:
str.extract(),str.contains()等可以组合使用 - 灵活性强:支持复杂的正则表达式
- 易于数据清洗:方便处理缺失值和异常数据
常见应用场景:
- 数据清洗(提取电话号码、邮箱、身份证号等)
- 文本分类(基于关键词或模式)
- 数据验证(格式检查)
- 信息抽取(从非结构化文本中提取结构化数据)
记住在使用正则时要注意:
- 使用原始字符串(
r'')避免转义问题 - 考虑边界情况和异常值
- 大数据集时优先使用向量化操作
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播