
本文旨在详细讲解如何利用Pandas库的`str.extract()`方法,结合正则表达式从包含混合类型数据的DataFrame列中精确提取特定模式。我们将深入探讨正则表达式的构建技巧,特别是处理多个可选模式和特殊字符的方法,并提供实际代码示例,帮助读者高效地清洗和分析复杂数据集。
在数据处理过程中,尤其是在从Excel或其他非结构化源导入数据时,Pandas DataFrame的列常常会包含混合类型的数据,例如字符串、数字以及各种编码模式。从这类列中准确识别并提取出特定信息,是数据清洗和预处理的关键一步。传统的方法可能需要复杂的条件判断,而正则表达式(Regex)则提供了一种强大且灵活的模式匹配机制,能够高效地从复杂字符串中抽取出符合特定规则的数据。
Pandas为字符串操作提供了一系列便捷的方法,集成在DataFrame或Series的.str访问器中。其中,str.extract()方法专门用于通过正则表达式从字符串中提取匹配的子串。它返回一个DataFrame,其中每一列对应正则表达式中的一个捕获组。如果正则表达式不包含捕获组,或者expand=False,则会返回一个Series。
基本语法:
Series.str.extract(pat, flags=0, expand=True)
本节将以从列中提取如"EE"、"AA"、"EA+"或"EA-"等特定代码为例,详细讲解如何构建正确的正则表达式。
假设我们需要从字符串中识别以下几种模式:
初学者常犯的一个错误是尝试使用字符集[]来表示多个可选的完整字符串,例如[EA+,AA,EA-]。然而,在正则表达式中,[]表示匹配方括号内任意一个字符。因此,[EA+,AA,EA-]会匹配E、A、+、,、-中的任意一个字符,而不是我们期望的完整字符串模式。
要匹配多个完整的可选字符串模式,应该使用管道符 | 作为“或”运算符,并将每个模式用括号 () 括起来形成捕获组。
此外,+和-在正则表达式中是特殊字符(分别表示“一个或多个”和“范围”)。如果它们作为字面字符出现,需要使用反斜杠 \ 进行转义。或者,当它们出现在字符集 [] 内部时,通常不需要转义(除非在特定位置,如[+-]表示匹配+或-)。
结合上述原则,我们可以构建出以下正则表达式:
(EE|AA|EA[+-])
如果只需要匹配 EE 和 AA,则可以简化为:
(EE|AA)
下面通过一个具体的代码示例来演示如何应用这些正则表达式。
首先,创建一个模拟原始Excel数据结构的DataFrame:
import pandas as pd
import numpy as np
# 模拟原始数据
data = {
'Nachfolger': [
'54;20', '----', '52;128AA;207;22;223', '----', '138EE;34',
'----', '139EE;36', '----', '140EE;38', '----', '141EE;40',
'21;4;49;50;51', '52', '52;24', '28', '52;227;27', '30',
'227', '52;31', 'SampleEA+text', 'AnotherEA-item' # 添加包含EA+和EA-的示例
]
}
df = pd.DataFrame(data)
print("原始DataFrame:")
print(df)现在,我们使用前面构建的正则表达式来提取模式。
示例一:提取 "EE" 或 "AA"
# 提取 'EE' 或 'AA'
df['Verknüpfung_EA_AA'] = df['Nachfolger'].str.extract(r'(EE|AA)', expand=True)
print("\n提取 'EE' 或 'AA' 后的DataFrame:")
print(df)示例二:提取 "EE"、"AA"、"EA+" 或 "EA-"
为了更全面地覆盖可能的需求,我们使用包含 EA[+-] 的正则表达式。
# 提取 'EE', 'AA', 'EA+' 或 'EA-'
df['Verknüpfung_Full'] = df['Nachfolger'].str.extract(r'(EE|AA|EA[+-])', expand=True)
print("\n提取 'EE', 'AA', 'EA+' 或 'EA-' 后的DataFrame:")
print(df)str.extract()在没有匹配时会返回NaN。根据需求,我们可以选择填充这些NaN值(例如用0或空字符串),或者直接进行计数。
填充 NaN 值:
# 填充 NaN 值为 '0'
df['Verknüpfung_EA_AA'] = df['Verknüpfung_EA_AA'].fillna('0')
df['Verknüpfung_Full'] = df['Verknüpfung_Full'].fillna('0')
print("\n填充 NaN 后的DataFrame:")
print(df)统计匹配项:
要统计每个模式的出现次数,可以使用value_counts()方法。
# 统计 'Verknüpfung_EA_AA' 列中非 '0' 模式的出现次数
print("\n'EE' 或 'AA' 模式的统计:")
print(df[df['Verknüpfung_EA_AA'] != '0']['Verknüpfung_EA_AA'].value_counts())
# 统计 'Verknüpfung_Full' 列中非 '0' 模式的出现次数
print("\n所有指定模式的统计:")
print(df[df['Verknüpfung_Full'] != '0']['Verknüpfung_Full'].value_counts())捕获组与返回DataFrame的列: str.extract()返回的DataFrame列数与正则表达式中的捕获组数量一致。如果只有一个捕获组,返回的DataFrame将只有一列。
非捕获组: 如果你只想使用括号进行分组而不希望其内容作为一个单独的列返回,可以使用非捕获组 (?:...)。例如 (?:EE|AA)。
str.contains(): 如果你只需要判断某个模式是否存在于字符串中,而不需要提取具体内容,可以使用df.str.contains(pat),它返回一个布尔Series。这在进行简单筛选或标记时非常有用。
性能考量: 对于非常大的数据集,复杂的正则表达式可能会影响性能。在可能的情况下,尽量优化正则表达式或考虑其他字符串处理方法。
多模式提取到不同列: 如果需要将不同的模式提取到不同的列中,可以为每个模式单独调用str.extract(),或者使用带有多个命名捕获组的正则表达式。
# 示例:将EE和AA分别提取到不同列
# 方法一:分别调用extract
df['Verknüpfung_EE'] = df['Nachfolger'].str.extract(r'(EE)', expand=True).fillna('0')
df['Verknüpfung_AA'] = df['Nachfolger'].str.extract(r'(AA)', expand=True).fillna('0')
print("\nEE和AA分别提取到不同列的DataFrame (方法一):")
print(df[['Nachfolger', 'Verknüpfung_EE', 'Verknüpfung_AA']])
# 方法二:使用命名捕获组(如果模式不重叠,且想一次性提取)
# 注意:如果同一行有多个匹配,只有第一个匹配会被提取到对应的命名组
# 更常见且健壮的做法是分开提取,或使用更复杂的regex确保只捕获一次
# 这里为了演示命名捕获组,我们假设模式是互斥的或者只关心第一个
df_extracted = df['Nachfolger'].str.extract(r'(?P<EE_Val>EE)|(?P<AA_Val>AA)|(?P<EA_Val>EA[+-])', expand=True)
df = pd.concat([df, df_extracted.fillna('0')], axis=1)
print("\n使用命名捕获组提取到不同列的DataFrame (方法二):")
print(df[['Nachfolger', 'EE_Val', 'AA_Val', 'EA_Val']])通过本文的学习,我们掌握了如何利用Pandas的str.extract()方法结合正则表达式,从DataFrame的混合数据列中高效地提取特定模式。关键在于正确理解并构建正则表达式,尤其是使用管道符|来表示可选模式,以及处理特殊字符。掌握这些技巧,将极大地提升您在数据清洗和预处理方面的能力,使您能够更精确地从复杂数据中获取所需信息,为后续的数据分析工作奠定坚实基础。
以上就是Pandas DataFrame中混合数据列的正则表达式模式提取与分析的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号