Pandas:如何从另一个字符串中提取字符串

2024-10-01 05:00:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个包含8000行的列,我需要创建一个新列,该列的值从现有列中提取

字符串如下所示:

TP-ETU06-01-525-W-133

我想从字符串中创建两个新列,其中第一个新列的值是从第二个字符串ETU06中提取的,第二个是从最后一个字符串133中提取的

我是通过以下方式做到这一点的:

df["sys_no"] = df.apply(lambda x:x["test_no"].split("-")[1] if (pd.notnull(x["test_no"]) and x["test_no"]!="" and len(x["test_no"].split("-"))>0) else None,axis=1)

df["package_no"] = df.apply(lambda x:x["test_no"].split("-")[-1] if (pd.notnull(x["test_no"]) and x["test_no"]!="" and len(x["test_no"].split("-"))>0) else None,axis=1)

它实际上工作得很好,但现有列具有不跟随其他列的随机字符串。因此,如果出现随机字符串,我希望在新列中留空

我应该如何更改脚本

谢谢


Tags: andlambdano字符串testnonedflen
2条回答

使用^{}作为掩码,然后按^{}拆分值,并通过仅按掩码索引筛选的行来选择secnd和last value:

print (df)
                 test_no
0              temp data
1                    NaN
2  TP-ETU06-01-525-W-133

mask = df["test_no"].str.contains('-', na=False)
splitted = df["test_no"].str.split("-")
df.loc[mask, "sys_no"] = splitted[mask].str[1]
df.loc[mask, "package_no"] = splitted[mask].str[-1]
print (df)
                 test_no sys_no package_no
0              temp data    NaN        NaN
1                    NaN    NaN        NaN
2  TP-ETU06-01-525-W-133  ETU06        133

    

这种方法使用regex和命名捕获组来查找和提取感兴趣的字符串,只需两行代码

regex对split:

的确,不需要正则表达式。然而,从数据验证的角度来看,使用正则表达式有助于防止“散乱”数据悄悄进入。使用'blind'split()函数拆分(字符)上的数据;但如果源数据发生了变化怎么办?拆分函数对此视而不见。然而,使用正则表达式将有助于突出一个问题,因为模式根本不匹配。是的,您可能会收到一条错误消息,但这是一件好事,因为您将收到数据格式更改的警报,从而有机会解决问题或更新正则表达式模式

此外,regex提供了一个健壮的解决方案,因为模式匹配整个字符串,并且忽略此模式之外的任何内容—如问题中提到的示例

如果您想对regex模式本身进行一些解释,只需添加一条注释,我将更新答案以进行解释

样本数据:

                 test_no
0  TP-ETU05-01-525-W-005
1  TP-ETU06-01-525-W-006
2  TP-ETU07-01-525-W-007
3  TP-ETU08-01-525-W-008
4  TP-ETU09-01-525-W-009
5                    NaN
6                    NaN
7             otherstuff

代码:

import re

exp = re.compile(r'^[A-Z]{2}-(?P<sys_no>[A-Z]{3}\d{2})-\d{2}-\d{3}-[A-Z]-(?P<package_no>\d{3})$')
df[['sys_no', 'package_no']] = df['test_no'].str.extract(exp, expand=True)

输出:

                 test_no  sys_no package_no
0  TP-ETU05-01-525-W-005   ETU05        005
1  TP-ETU06-01-525-W-006   ETU06        006
2  TP-ETU07-01-525-W-007   ETU07        007
3  TP-ETU08-01-525-W-008   ETU08        008
4  TP-ETU09-01-525-W-009   ETU09        009
5                    NaN     NaN        NaN
6                    NaN     NaN        NaN
7             otherstuff     NaN        NaN

相关问题 更多 >