python - 使用 python 的正则表达式比较和提取字母字符

标签 python regex dataframe

您好,我有一个数据集,如下所示:

Format,Message,time
A,ab@1 yl@5 rd@20 pp@40,3
B,bc@1 gn@7 yl@20 ss@25 rd@50, 21
C,cc@1 yl@9 rd@20, 22

我想使用从消息 yl 和 rd 中提取的数字,然后对其数字(例如 yl@5 ---> 5)和时间列的数字进行比较。因此,如果第 1、3 行将与第 5 和 20 行进行比较。因此,如果它小于这两个元素,则会为其分配值 g。如果时间为 7,则将分配值 y,同样,如果时间为 20 及以上,则将分配为 r。

所以会像

Format,Message,time,status
A,ab@1 yl@5 rd@20 pp@40,3,g
B,bc@1 gn@7 yl@20 ss@25 rd@50,21,y
C,cc@1 yl@9 rd@20,22,r

最佳答案

你的问题确实是很多问题。从“dataframe”标签来看,您似乎正在使用 pandas 执行此操作。您询问的正则表达式可以额外添加“yl”和“rd”的数字(如果有的话,我假设它们总是存在)。但正则表达式通常不进行数学或数值比较,因此这是第三位。

匹配“yl”数值的正则表达式(假设为整数,而不是 float ):

r'yl@(\d+)'

您可以将它们提取到单个表达式中,但这会假设它们始终处于相同的顺序,或者成为复杂的正则表达式。

为了确保只有 yl@5 匹配,但像 xyl@5 这样的东西不匹配,您可以在开头添加一些限制(需要空格或行开头) ) 和结尾(需要空格或行尾):

r'(^|\s)yl@(\d+)($|\s)'

或者,如果您遇到 yl 是命名空间的情况,例如 a:yl,您也可以添加它:

r'(^|\s)([a-z]+:)?l@(\d+)($|\s)'

然而,这一切只是使用正则表达式语言构建更具体的表达式。我喜欢使用(无隶属关系)的一个非常好的编写正则表达式的工具是 RegexBuddy,但也有非常好的在线工具,例如 https://regex101.com/ .

在代码示例中使用,基本上按照您的建议进行操作:

import re
from pandas import DataFrame

df = DataFrame({
    'Format': ['A', 'B', 'C'],
    'Message': ['ab@1 yl@5 rd@20 pp@40', 'bc@1 gn@7 yl@20 ss@25 rd@50', 'cc@1 yl@9 rd@20'],
    'time': [3, 21, 22]
})


def determine_status(row):
    def find(tag, message):
        match = re.search(rf"{tag}@(\d+)", message)
        if match:
            return match.group(1)
        else:
            raise ValueError(f'{tag} not in message.')

    yl = int(find('yl', row['Message']))
    rd = int(find('rd', row['Message']))

    time = int(row['time'])
    if time < yl < rd:
        return 'g'
    if yl <= time < rd:
        return 'y'
    return 'r'


df['status'] = df.apply(determine_status, axis=1)

print(df)

find 函数接受一个标签和一条消息,并使用正则表达式为消息中的标签生成数值。

define_status 函数就是这样做的 - 它需要来自 DataFrame 的一行,并将使用 Messagetime 列来确定状态并返回它。

然后使用

df.apply 创建一个新的 status 列,并用 DataFrame 中每一行的 define_status 的结果填充它.

您没有指定您使用的Python版本,但如果是Python 3.6之前的版本,您会发现message中没有像f'{tag}这样的表达式。'不起作用 - 相反,您可以使用类似 '{tag} not in message.'.format(tag=tag).

关于python - 使用 python 的正则表达式比较和提取字母字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53773067/

相关文章:

python - 根据分隔符将数据帧列拆分为两列

r - 从嵌套列表中提取然后 row.bind data.frames

python - 绘制 100% 堆积图问题

python - 与python的网络连接

python - 安装旧版本 python 时保留当前版本

JavaScript 找到 "/"并替换为 "_"

Python查找所有出现的连字符单词并替换该位置

c# - 从字符串中检索文本的正则表达式

java - 删除 Re : Fwd: from Mail subjects

python - 如何在 to_json 中包含 Dataframe 的名称(Pandas)