
在数据处理和分析中,我们经常需要对dataframe中的文本数据进行操作,例如从现有字符串列中提取特定模式的信息(如数字、日期、特定关键词),然后将其与固定的文本片段组合,生成新的、具有业务含义的字符串列。这种需求在报告生成、数据清洗和特征工程中非常普遍。pandas提供了强大的字符串处理能力,特别是通过其str访问器,可以实现向量化的字符串操作。
假设我们有一个Pandas DataFrame,其中包含一列如PROJEKT[BEZEICHNUNG]的字符串数据,其内容可能包含多个数字。我们的目标是从这些字符串中提取出特定的数字(例如,第一个和第二个数字),并将它们与预设的文本(如“P”和“Stufe”)拼接成一个新的字符串,存储在一个新列EINGRUPPIERUNG中。
一个常见的初学者误区是试图直接对str.findall返回的Series进行列表索引操作,例如:
# 假设df["PROJEKT[BEZEICHNUNG]"].str.findall(r"\d+") 结果为 Series([['8', '4'], ['8', '5'], ...]) # 错误的尝试: # df["EINGRUPPIERUNG"] = "P" + df["PROJEKT[BEZEICHNUNG]"].str.findall(r"\d+")[:][0] + \ # " Stufe " + df["PROJEKT[BEZEICHNUNG]"].str.findall(r"\d+")[:][1]
这种做法的问题在于,df["PROJEKT[BEZEICHNUNG]"].str.findall(r"\d+")返回的是一个Pandas Series,其中每个元素本身是一个数字列表。对这个Series直接使用[:][0]会尝试获取整个Series的第一个元素(即第一个列表['8', '4']),而不是每个列表中的第一个数字。这会导致类型不匹配错误,因为我们试图将一个字符串与一个列表进行拼接。正确的做法是利用Pandas的str访问器对Series中的每个列表元素进行索引。
这种方法分两步进行:首先使用str.findall通过正则表达式提取所有匹配的数字,得到一个Series,其中每个元素是一个列表;然后,利用str访问器对这些列表进行索引,获取我们需要的特定数字,最后进行字符串拼接。
import pandas as pd
# 示例数据
data = {
'PROJEKT[BEZEICHNUNG]': [
'blah 8 blah 4',
'blah 8 blah 5',
'blah 8 blah 5',
'blah 7 blah 4',
'another 9-3 project',
'only one number 10 here' # 示例,处理只有一个数字的情况
]
}
df = pd.DataFrame(data)
print("原始DataFrame:")
print(df)
# 1. 使用str.findall提取所有数字
# 结果是一个Series,每个元素是一个数字字符串列表
match_lists = df['PROJEKT[BEZEICHNUNG]'].str.findall(r'\d+')
print("\n提取的数字列表 Series:")
print(match_lists)
# 2. 使用str访问器对列表进行索引,获取第一个和第二个数字
# match_lists.str[0] 会获取每个列表的第一个元素
# match_lists.str[1] 会获取每个列表的第二个元素
# 如果列表长度不足,str[index] 会返回 NaN
first_num = match_lists.str[0]
second_num = match_lists.str[1]
# 3. 拼接字符串
# 注意:如果second_num中存在NaN(即原始字符串中没有第二个数字),
# 拼接结果也会包含NaN。我们可以使用fillna('')来处理。
df['EINGRUPPIERUNG_Method1'] = 'P' + first_num.fillna('') + ' Stufe ' + second_num.fillna('')
print("\n使用str.findall和str索引拼接的结果:")
print(df)
# 进一步处理NaN的改进示例:如果第二个数字不存在,则不显示“Stufe”部分
df['EINGRUPPIERUNG_Method1_Improved'] = df.apply(
lambda row: 'P' + row['PROJEKT[BEZEICHNUNG]'].str.findall(r'\d+')[0] + \
(' Stufe ' + row['PROJEKT[BEZEICHNUNG]'].str.findall(r'\d+')[1] if len(row['PROJEKT[BEZEICHNUNG]'].str.findall(r'\d+')) > 1 else ''),
axis=1
)
print("\n改进后的结果(处理缺失第二个数字,更灵活的条件拼接):")
print(df)优点: 灵活性高,可以提取任意数量的匹配项并进行精细控制。 缺点: 需要手动处理可能因列表长度不足而产生的NaN值,代码可能略显冗长。
如果正则表达式能够清晰地定义并捕获我们所需的所有数字片段,str.extract是一个更简洁、更直接的方法。它会根据正则表达式中的捕获组,将提取出的数据作为新的列返回一个DataFrame。
import pandas as pd
# 示例数据
data = {
'PROJEKT[BEZEICHNUNG]': [
'blah 8 blah 4',
'blah 8 blah 5',
'blah 8 blah 5',
'blah 7 blah 4',
'another 9-3 project',
'only one number 10 here' # 示例,处理只有一个数字的情况
]
}
df = pd.DataFrame(data)
# 使用str.extract,正则表达式捕获两个数字
# r'(\d+).*?(\d+)':匹配第一个数字(\d+),非贪婪匹配任意字符(.*?), 再匹配第二个数字(\d+)
# expand=True 会将捕获组作为独立的列返回一个DataFrame
# 如果正则表达式不匹配,则返回NaN
match_df = df['PROJEKT[BEZEICHNUNG]'].str.extract(r'(\d+).*?(\d+)', expand=True)
print("\n使用str.extract提取的DataFrame:")
print(match_df)
# 拼接字符串
# match_df[0] 和 match_df[1] 分别对应第一个和第二个捕获组
# 同样需要处理可能存在的NaN值
df['EINGRUPPIERUNG_Method2'] = 'P' + match_df[0].fillna('') + ' Stufe ' + match_df[1].fillna('')
print("\n使用str.extract拼接的结果:")
print(df)优点: 代码简洁,直接返回结构化的DataFrame,易于拼接。 缺点: 正则表达式必须能够准确匹配所有捕获组,否则未匹配的捕获组会生成NaN。如果字符串格式不规则,可能需要更复杂的正则表达式。
如果目标是根据匹配的模式完全替换原字符串的一部分或全部内容,str.replace配合正则表达式的反向引用(backreferences,如\1, \2)可以实现非常高效且简洁的字符串转换。
import pandas as pd
# 示例数据
data = {
'PROJEKT[BEZEICHNUNG]': [
'blah 8 blah 4',
'blah 8 blah 5',
'blah 8 blah 5',
'blah 7 blah 4',
'another 9-3 project',
'only one number 10 here' # 示例
]
}
df = pd.DataFrame(data)
# 使用str.replace,捕获数字并用反向引用\1, \2在替换字符串中使用
# r'.*?(\d+).*?(\d+).*' 匹配整个字符串,捕获两个数字
# r'P\1 Stufe \2' 是替换字符串,\1和\2引用捕获到的数字
# regex=True 必须设置为True才能使用正则表达式
df['EINGRUPPIERUNG_Method3'] = df['PROJEKT[BEZEICHNUNG]'].str.replace(
r'.*?(\d+).*?(\d+).*', r'P\1 Stufe \2', regex=True
)
print("\n使用str.replace拼接的结果:")
print(df)优点: 代码极其简洁,一行即可完成提取和替换。 缺点: 如果原字符串不完全匹配正则表达式,或者只需要替换部分内容而不是整个字符串,其行为可能不符合预期(未匹配的行将保持不变)。这种方法更适合于将整个字符串转换为新的格式。
以上就是Pandas中高效拼接文本与正则表达式提取的数字的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号