从pandas中字符串、数字和特殊字符的组合中查找模式

2024-06-26 14:47:44 发布

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

我有一个数据框,如下所示

COURSE_ID
INC-AAB-WW-105614
INC-AAB-DE-234567
INC-AAB-NL-WFT-PA-BS-123489
INC-AAB-NL-WFT-PA-SI-145678-SYS-2020
EXI-WDFT-145678

从这里我只需要取

  • 公司部分
  • AAB部分
  • WW/DE/NL/AU/NW(如图所示),其中有国家代码和
  • 6位课程代码105614/234567/123489

对于不是以INC-AAB开头的其余部分,将保持不变。国家代码可在另一个查找表中找到。最后的数据帧看起来是这样的

COURSE_ID
INC-AAB-WW-105614
INC-AAB-DE-234567
INC-AAB-NL-123489
INC-AAB-NL-145678
EXI-WDFT-145678  

Tags: 数据代码idbsnlde国家inc
3条回答

熊猫不是我的强项,但也许有些东西在替换功能中使用常规的epxpress

df['COURSE_ID'] = df['COURSE_ID'].str.replace(r'^(INC-AAB-[A-Z]+).*?(-\d{6})\b.*$', r'\1\2')
print(df)

印刷品:

           COURSE_ID
0  INC-AAB-WW-105614
1  INC-AAB-DE-234567
2  INC-AAB-NL-123489
3  INC-AAB-NL-145678
4    EXI-WDFT-145678

{}背后的理念是:

  • ^-开始线锚
  • (INC-AAB-[A-Z]+)-第一个捕获组,包含所需的“INC-AAB-”开头和任何1+大写字符(alpha)
  • .*?-0+个字符的延迟匹配,最多为
  • (-\d{6})-第二个捕获组,包含您所需的连字符模式和最多6个数字
  • \b.*-字边界和0+(贪婪)字符
  • $-结束线锚定

我们可以连接所有捕获组以获得您想要的结果:

\1\2

请参阅联机demo

下面是另一个使用^{}的选项,用于更简单的正则表达式

如果不以INC开头,则保留df.COURSE_ID,否则^{}正则表达式:

regex = r'(INC-AAB)-(WW|DE|NL|AU|NW).*(\d{6})'

df['COURSE_ID'] = df.COURSE_ID.where(
    ~df.COURSE_ID.str.startswith('INC'),
    df.COURSE_ID.str.extract(regex).dropna().agg('-'.join, axis=1)
)

#            COURSE_ID
# 0  INC-AAB-WW-105614
# 1  INC-AAB-DE-234567
# 2  INC-AAB-NL-123489
# 3  INC-AAB-NL-145678
# 4    EXI-WDFT-145678

请您尝试以下方法:

df['COURSE_ID'] = df['COURSE_ID'].str.replace(r'^(INC-AAB-[A-Z]+-)(?:[A-Z]+-)*(\d+).*', r'\1\2')
  • ^(INC-AAB-[A-Z]+-)匹配的子字符串INC-AAB-位于 字符串后跟国家代码和连字符。然后是匹配的 子字符串在组1中捕获(由\1引用)
  • (?:[A-Z]+-)*匹配被丢弃的可选国家/地区代码
  • (\d+)匹配组2中捕获的课程代码(\2
  • .*匹配被丢弃的剩余片段

输出:

           COURSE_ID
0  INC-AAB-WW-105614
1  INC-AAB-DE-234567
2  INC-AAB-NL-123489
3  INC-AAB-NL-145678
4    EXI-WDFT-145678

相关问题 更多 >