在 pandas 列中提取正则表达式

Posted

技术标签:

【中文标题】在 pandas 列中提取正则表达式【英文标题】:Extract regex in pandas column 【发布时间】:2021-10-05 12:56:00 【问题描述】:

您好,我希望将 Df 列中不同产品的件数放入一个新列中。目前,数字排在产品类型之后。

数据如下:

PRODUCTS
PULSAR AT 20 MG ORAL 30 TAB RECUB
LIPITOR 40 MG 1+1 ORAL 15 TAB
LOFTYL 150 MG ORAL 30 TAB
SOMAZINA 500 MG ORAL 10 COMP RECUB
LOFTYL 30 TAB 150 MG ORAL 
*Keeps going more entries...*

我的函数如下所示:

df['PZ'] = df['PRODUCTS'].str.extract('([\d]*\.*[\d]+)\s*[tab|cap|grag|past|sob]',flags=re.IGNORECASE)

产品可以是 [TAB、COMP、AMP、SOB、PAST、GRAG ... 等]

我想得到这样的东西:

PRODUCTS                              PZ
PULSAR AT 20 MG ORAL 30 TAB RECUB     30
LIPITOR 40 MG 1+1 ORAL 15 TAB         15
LOFTYL 150 MG ORAL 30 TAB             30
SOMAZINA 500 MG ORAL 10 COMP RECUB    10
LOFTYL 30 TAB 150 MG ORAL             30

我可以在我的行中更改什么以获得如下结果?

感谢您阅读我和您的帮助。

【问题讨论】:

SOMAZINA 500 MG ORAL 10 COMP RECUB 如何匹配 '([\d]*\.*[\d]+)\s*[tab|cap|grag|past|sob]' ?? 【参考方案1】:

你可以使用

import pandas as pd
df = pd.DataFrame('PRODUCTS':['PULSAR AT 20 MG ORAL 30 TAB RECUB','LIPITOR 40 MG 1+1 ORAL 15 TAB','LOFTYL 150 MG ORAL 30 TAB','SOMAZINA 500 MG ORAL 10 COMP RECUB','LOFTYL 30 TAB 150 MG ORAL'])
rx = r'(?i)(\d*\.?\d+)\s*(?:tab|cap|grag|past|sob|comp)'
df['PZ'] = df['PRODUCTS'].str.extract(rx)
>>> df
                             PRODUCTS  PZ
0   PULSAR AT 20 MG ORAL 30 TAB RECUB  30
1       LIPITOR 40 MG 1+1 ORAL 15 TAB  15
2           LOFTYL 150 MG ORAL 30 TAB  30
3  SOMAZINA 500 MG ORAL 10 COMP RECUB  10
4           LOFTYL 30 TAB 150 MG ORAL  30
>>> 

如果tabcap等词是整个词且不能是较长词的一部分,则需要在模式末尾添加词边界,即rx = r'(?i)(\d*\.?\d+)\s*(?:tab|cap|grag|past|sob|comp)\b'.

请参阅regex demo。 详情

(?i) - 不区分大小写的内联修饰符 (\d*\.?\d+) - 第 1 组:零位或多位数字,可选的 .,然后是一位或多位数字 \s* - 零个或多个空白字符 (?:tab|cap|grag|past|sob|comp) - 一个非捕获组(以免干扰Series.str.extract 输出)匹配其中的任何替代子字符串 \b - 单词边界。

【讨论】:

【参考方案2】:

也许……

给定一个数据框(注意:我让产品在一行中出现两次作为示例,以防发生这种情况)...

    PRODUCTS
0   PULSAR AT 20 MG ORAL 30 GRAG RECUB
1   LIPITOR 40 MG 1+1 ORAL 15 TAB
2   LOFTYL 150 GRAG ORAL 30 TAB
3   SOMAZINA 500 MG ORAL 10 COMP RECUB
4   LOFTYL 30 TAB 150 MG ORAL
5   *Keeps going more entries...*

代码:

import pandas as pd
import re

data = 'PRODUCTS' : ["PULSAR AT 20 MG ORAL 30 GRAG RECUB", "LIPITOR 40 MG 1+1 ORAL 15 TAB", \
                      "LOFTYL 150 GRAG ORAL 30 TAB", "SOMAZINA 500 MG ORAL 10 COMP RECUB", \
                      "LOFTYL 30 TAB 150 MG ORAL" , "*Keeps going more entries...*"]

df = pd.DataFrame(data)

# maintain a list of products to find
products = ['TAB', 'COMP', 'AMP', 'SOB', 'PAST', 'GRAG']

def getProduct(x):
    found = list()
    for product in products:
        pattern = r'(\d+)' + ' ' + str(product)
        found.append(re.findall(pattern, x))
    found = list(filter(None, found))
    found = [item for sublist in found for item in sublist]
    found = ", ".join(str(item) for item in found)
    return found

df['PZ'] = [getProduct(row) for row in df['PRODUCTS']]

print(df)

输出:

    PRODUCTS                            PZ
0   PULSAR AT 20 MG ORAL 30 GRAG RECUB  30
1   LIPITOR 40 MG 1+1 ORAL 15 TAB       15
2   LOFTYL 150 GRAG ORAL 30 TAB         30, 150
3   SOMAZINA 500 MG ORAL 10 COMP RECUB  10
4   LOFTYL 30 TAB 150 MG ORAL           30
5   *Keeps going more entries...*   

【讨论】:

以上是关于在 pandas 列中提取正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

Pandas 正则表达式返回括号中的值

熊猫正则表达式提取物为 re.search 提供不同的输出?

pandas 按正则表达式条件从列中过滤字符串并替换它

使用正则表达式从 mysql 列中提取子字符串

从 pandas DataFrame 中的列中提取 JSON 数据

通过正则表达式提取excel特定列中含有关键字的所有行数据