将Regex应用于df在新列中添加值

时间:2017-02-15 10:21:30

标签: python regex

这是我的数据集:

BlaBla 128 MB EE
ADTD 6 gb DTS
EEEDC 2GB RS
STA 12MB DFA
BBNB 32 mb YED

从这个数据集中我想提取MB / GB的数量和单位MB / GB。因此我创建了以下正则表达式:

(\d*)\s?(MB|GB)

我创建的代码是为了将正则表达式应用于我的df:

pattern = re.compile(r'(\d*)\s?(MB|GB)')
invoice_df['mbs'] = invoice_df['Rate Plan'].apply(lambda x: pattern.search(x).group(1))
invoice_df['unit'] = invoice_df['Rate Plan'].apply(lambda x: pattern.search(x).group(2))

然而,当将正则表达式应用于我的df时,它会给出以下错误消息:

AttributeError: 'NoneType' object has no attribute 'group'

我该怎么做才能解决这个问题?

2 个答案:

答案 0 :(得分:1)

由于某些条目可能不匹配,因此re.search失败(返回不匹配)。您需要在lambda中考虑这些情况:

apply(lambda x: pattern.search(x).group(1) if pattern.search(x) else "")

我也建议使用

(?i)(\d+)\s*([MGK]B)

它会找到1位​​数字(\d+,第1组),后跟0 +空格(\s*),并且会匹配KBGB,{{1}以不区分大小写的方式进入第2组(MB)。

答案 1 :(得分:0)

您只需要在请求群组之前检查是否找到了某些内容:

import re

inputs = ["BlaBla 128 MB EE",
"ADTD 6 gb DTS",
"EEEDC 2GB RS",
"STA 12MB DFA",
"BBNB 32 mb YED",
"Nothing to find here"]

pattern = re.compile("(\d+)\s*([MG]B)", re.IGNORECASE)

for input in inputs:
    match = re.search(pattern, input)
    if match:
        mbs = match.group(1)
        unit = match.group(2)
        print (mbs, unit.upper())
    else:
        print "Nothing found for : %r" % input

# ('128', 'MB')
# ('6', 'GB')
# ('2', 'GB')
# ('12', 'MB')
# ('32', 'MB')
# Nothing found for : 'Nothing to find here'

使用您的代码:

pattern = re.compile("(\d+)\s*([MG]B)", re.IGNORECASE)
match = re.search(pattern, invoice_df['Rate Plan'])
if match:
    invoice_df['mbs'] = match.group(1)
    invoice_df['unit'] = match.group(2)

它比lambda恕我直言更具可读性,并且它不会执行两次搜索。