
在数据分析和处理过程中,我们经常需要从非结构化的文本数据中提取特定信息,并将其与其他字符串拼接,以生成新的、结构化的描述性字段。例如,从包含项目描述的字符串中提取版本号或阶段号,并将其与预设文本组合成一个新的分类字段。本文将详细介绍如何使用pandas的字符串(str)访问器结合正则表达式来实现这一目标,主要涵盖str.findall、str.extract和str.replace三种方法。
首先,我们创建一个示例Pandas DataFrame,其中包含一个需要处理的文本列。
import pandas as pd
import re
# 示例数据
data = {
'PROJEKT[BEZEICHNUNG]': [
'项目A 版本8 阶段4',
'项目B 版本8 阶段5',
'项目C 版本7 阶段5',
'项目D 版本7 阶段4',
'项目E 版本9 阶段3',
'无有效数字描述', # 用于演示无匹配情况
'特殊格式版本10 阶段12' # 用于演示多位数提取
]
}
df = pd.DataFrame(data)
print("原始DataFrame:")
print(df)
print("-" * 30)str.findall(pattern) 方法会在Series的每个字符串中查找所有与正则表达式pattern匹配的非重叠项,并返回一个列表。如果需要提取多个数字并分别使用,可以通过Series的str访问器进一步索引这些列表中的元素。
步骤:
# 1. 使用 str.findall 提取所有数字
# 结果将是一个Series,其中每个元素是一个包含所有匹配数字的列表
match_lists = df['PROJEKT[BEZEICHNUNG]'].str.findall(r'\d+')
print("使用 str.findall 提取的数字列表:")
print(match_lists)
print("-" * 30)
# 2. 访问列表中的元素并进行拼接
# 注意:如果某个列表为空或元素不足,访问会出错。
# 我们可以使用 .fillna('') 或其他策略处理,这里为了演示先假设数据完整。
# 对于 '无有效数字描述' 这一行,match_lists.str[0] 和 match_lists.str[1] 会得到 NaN。
# 在拼接时,NaN 会导致整个字符串变成 NaN。
df['EINGRUPPIERUNG_Method1'] = 'P' + match_lists.str[0].fillna('') + ' Stufe ' + match_lists.str[1].fillna('')
print("使用 str.findall 和 str 索引创建的新列:")
print(df[['PROJEKT[BEZEICHNUNG]', 'EINGRUPPIERUNG_Method1']])
print("-" * 30)注意事项:
str.extract(pattern) 方法更适合于从字符串中提取具有特定结构(由正则表达式的捕获组定义)的数据。它会返回一个DataFrame,其中每个捕获组对应一列,这使得访问和组合提取的数据变得更加直观和安全。
步骤:
# 1. 使用 str.extract 提取捕获组
# 正则表达式 r'(\d+).*?(\d+)' 匹配第一个数字序列和第二个数字序列
# .*? 表示非贪婪匹配任意字符,直到下一个数字序列
extracted_df = df['PROJEKT[BEZEICHNUNG]'].str.extract(r'(\d+).*?(\d+)')
print("使用 str.extract 提取的DataFrame:")
print(extracted_df)
print("-" * 30)
# 2. 访问提取的列并进行拼接
# extracted_df 的列名默认为 0, 1, ...
df['EINGRUPPIERUNG_Method2'] = 'P' + extracted_df[0].fillna('') + ' Stufe ' + extracted_df[1].fillna('')
print("使用 str.extract 创建的新列:")
print(df[['PROJEKT[BEZEICHNUNG]', 'EINGRUPPIERUNG_Method2']])
print("-" * 30)注意事项:
str.replace(pattern, repl, regex=True) 方法可以在一个步骤内完成匹配和替换。如果替换字符串repl中包含反向引用(如, ),则可以直接将捕获组的内容插入到替换字符串中,实现一步到位的数据转换。
步骤:
# 1. 使用 str.replace 结合反向引用进行替换
# 正则表达式 r'.*?(\d+).*?(\d+).*?' 匹配整个字符串,并捕获两个数字序列
# 替换字符串 r'P\1 Stufe \2' 将捕获的数字插入到指定位置
df['EINGRUPPIERUNG_Method3'] = df['PROJEKT[BEZEICHNUNG]'].str.replace(
r'.*?(\d+).*?(\d+).*?',
r'P\1 Stufe \2',
regex=True
)
# 处理未匹配项:str.replace 如果不匹配,则不进行替换,保持原样。
# 如果我们希望未匹配项变成空字符串或特定值,需要额外处理。
# 例如,可以先用fillna('')处理,或在替换后再次检查。
# 这里为了演示,我们先展示替换结果。
# 对于 '无有效数字描述' 这一行,由于不匹配正则表达式,它将保持原样。
# 如果需要将其转换为 NaN 或空字符串,可以进行后续处理,例如:
# df.loc[~df['PROJEKT[BEZEZEICHNUNG]'].str.contains(r'\d+.*?(\d+)'), 'EINGRUPPIERUNG_Method3'] = ''
print("使用 str.replace 创建的新列:")
print(df[['PROJEKT[BEZEICHNUNG]', 'EINGRUPPIERUNG_Method3']])
print("-" * 30)注意事项:
本文介绍了在Pandas中结合正则表达式从文本列中提取数字并组合字符串的三种主要方法:str.findall结合str索引、str.extract和str.replace。
选择哪种方法取决于具体需求:
通用注意事项:
通过灵活运用这些Pandas功能,可以高效地完成复杂的文本数据清洗和转换任务。
以上就是Pandas中利用正则表达式提取数字并组合字符串的教程的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号