【问题标题】:Multiple Pattern using Regex in Pandas在 Pandas 中使用正则表达式的多种模式
【发布时间】:2017-10-30 08:53:21
【问题描述】:

我是 Python 编程的初学者。我正在探索正则表达式。我正在尝试从描述列中提取一个单词(数据库名称)。我无法提供多个正则表达式模式。

请看下面的描述和代码。

说明

Summary: AD1: Low free DATA space in database AD1ADS: 10.00% Date: 06/28/2017 Severity: Warning Res
Summary: Database SV1V1CH has used log space: 90.00% Date: 02/06/2017 Severity: Warning ResourceId: s
Summary: SAP SolMan Sys=SM1Tempdb,MO=AGEEPM49,Alert=Database Host Status,Desc=A database hos
*** Clearing Event Received *** SNG01AMMSOL04_age SAP SolMan Sys=SM1_SNG01AMMSOL04,MO=AGEEQM46,Alert

提取的数据库名称的预期输出

AD1ADS
SV1V1CH
SM1Tempdb
SNG01AMMSOL04

代码尝试

sentence = df['Description']
frame = pd.DataFrame({'logs': sentence})

import re
pattern = re.compile(r'[dD]atabase (\w+)|Sys=(\w+)')

for _, line in frame.iterrows():
    name = pattern.findall(line['logs'])
    if name:
        line['names'] = name[0]
    else:
        line['names'] = 'Miscellaneous'

谁能告诉我,我在这里做错了什么。

我现在得到的输出

(u'AD1ADS', u'')
(u'SV1V1CH', u'')
(u'', u'CM1_CHE01AMMSOL04')
Miscellaneous

【问题讨论】:

  • 你得到了什么输出?请同时发布
  • 请看已编辑的。我也发布了我的答案
  • 看看@jezrael 的答案,这就是你可以在熊猫中做到的方式

标签: python pandas python-2.7


【解决方案1】:

您可以将str.extractfillna 一起使用:

p = r'[dD]atabase (\w+)|Sys=(\w+)'
s = df['logs'].str.extract(p, expand=True)
print (s)
         0                  1
0   AD1ADS                NaN
1  SV1V1CH                NaN
2      NaN          SM1Tempdb
3      NaN  SM1_SNG01AMMSOL04

df['db'] = s[0].fillna(s[1]).fillna('Miscellaneous')
#alternatively 
#df['db'] = s[0].combine_first(s[1]).fillna('Miscellaneous')
print (df)
                                                logs                 db
0  Summary: AD1: Low free DATA space in database ...             AD1ADS
1  Summary: Database SV1V1CH has used log space: ...            SV1V1CH
2  Summary: SAP SolMan Sys=SM1Tempdb,MO=AGEEPM49,...          SM1Tempdb
3  *** Clearing Event Received *** SNG01AMMSOL04_...  SM1_SNG01AMMSOL04

如果要提取所有可能的值,请使用extractall,然后在必要时使用join

p = r'[dD]atabase (\w+)|Sys=(\w+)'
s = df['logs'].str.extractall(p)
print (s)
               0                  1
  match                            
0 0       AD1ADS                NaN
1 0      SV1V1CH                NaN
2 0          NaN          SM1Tempdb
  1         Host                NaN
  2          hos                NaN
3 0          NaN  SM1_SNG01AMMSOL04

df['db'] = s[0].fillna(s[1]).groupby(level=0).apply(', '.join)
df['db'] = df['db'].fillna('Miscellaneous')
print (df)
                                                logs                    db
0  Summary: AD1: Low free DATA space in database ...                AD1ADS
1  Summary: Database SV1V1CH has used log space: ...               SV1V1CH
2  Summary: SAP SolMan Sys=SM1Tempdb,MO=AGEEPM49,...  SM1Tempdb, Host, hos
3  *** Clearing Event Received *** SNG01AMMSOL04_...     SM1_SNG01AMMSOL04

【讨论】:

  • p = r'[dD] 数据库 (\w+)|Sys=(\w+)| SAP: (\w+)' s = frame['logs'].str.extract(p, expand=True) print (s) frame['DBNames'] = s[0].fillna(s[1]) frame ['DBNames'] = s[0].fillna(s[2]) 我可以修改如下,针对多个条件
  • 感谢 Ashish 和 @jezrael
  • @BPK - 你想要多个条件的新列吗?对于每个模式一个新列?
  • 是的。截至目前,我能够看到两个匹配条件的列 0 和 1,并使用 df['db'] = s[0].fillna(s[1]).groupby(level=0).apply 将其组合(', '.join) 但是,现在添加另一个条件,比如 - p = r'[dD]atabase (\w+)|Sys=(\w+)|SAP: (\w+)' 我如何组合 0,1和 2. 更换 NAs
  • 我明白了,需要s.apply(lambda x: ','.join(x.dropna()), axis=1).groupby(level=0).apply(', '.join) - 它可以很好地处理多个列
【解决方案2】:
p = r'[dD]atabase (\w+)|Sys=(\w+)|SAP: (\w+)'
s = df['logs'].str.extractall(p)
print (s)

df['DBNames'] = s.apply(lambda x: ','.join(x.dropna()),axis=1).groupby(level=0).apply(', '.join)
df['DBNames'] = df['DBNames'].fillna('Miscellaneous')
print df

这对我有用:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-24
    • 2014-09-05
    • 1970-01-01
    • 2019-10-23
    • 2019-07-25
    • 1970-01-01
    相关资源
    最近更新 更多