如何从 Python 中的文本中提取 2d 年?

Posted

技术标签:

【中文标题】如何从 Python 中的文本中提取 2d 年?【英文标题】:How to extract 2d year from text in Python? 【发布时间】:2021-12-21 12:09:47 【问题描述】:

我试图从 Pandas DataFrame 中的一列中的短文本中提取出生年份和死亡年份:

firstname lastname (1937-2015)

我用这个代码得到了第一年:

data = re.findall(r'\d+', txt)
if len(data) > 0 :
    data = float(data[0])
    if data >= 1800 and data <= 2021 :
        return data
return None

但我无法从文本中提取第二年。 例如,当我将data[0] 更改为data[1] 时,我收到一条错误消息“列表索引超出范围”

【问题讨论】:

【参考方案1】:

您可以定义 2 个捕获组并检查它们

df = pd.DataFrame(
    'txt': ['firstname lastname (1937-2015)', 'firstname lastname (1780-1820)',
             'firstname lastname (1945-?)', 'firstname lastname (1980-2022)'])

df[['birth', 'death']] = df['txt'].str.extract(r'(\d+)-(\d+|\?)').replace('?': None).astype(float). \
    applymap(lambda x: x if 1800 <= x <= 2021 else None)
print(df)

输出:

                              txt   birth   death
0  firstname lastname (1937-2015)  1937.0  2015.0
1  firstname lastname (1780-1820)     NaN  1820.0
2     firstname lastname (1945-?)  1945.0     NaN
3  firstname lastname (1980-2022)  1980.0     NaN

【讨论】:

您好,非常感谢您的帮助。它工作得很好。我现在发现了错误,因为有些行只有一年(只有出生年份),而其他行有特殊字符而不是年份(比如 1945-?)。我该如何管理?我需要提取 2 个不同的序列吗?使用 : r'(\d+)-* 和另一个使用 : r'.*-(\d4)' ? 您可以在 r'(\d+)-(\d+|\?)' 这样的一个表达式中处理变体 (1937-2015)(1945-?) - 请参阅更新的代码【参考方案2】:

使用您可以利用的Series.str.extract 在 Pandas 中提取第二年(从 1800 到 2099)的通用正则表达式解决方案

import pandas as pd
df = pd.DataFrame('col':['firstname lastname (1937-2015)'])
yr = r'(?:1[89][0-9]2|20[01][0-9]|202[01])'
df['second_year'] = df['col'].str.extract(fr'(?s)(?<!\d)yr(?!\d).*?(yr)(?!\d)')
# => df['second_year']
#   0    2015
#   Name: second_year, dtype: object

请参阅regex demo。 详情

(?s) - . 现在跨行匹配 (?&lt;!\d) - 左侧数字边界 (?:1[89][0-9]2|20[01][0-9]|202[01]) - 从 1800 年到 2021 年 (?!\d) - 右手数字边界 .*? - 任何文本,尽可能少的字符 (1[89][0-9]2|20[01][0-9]|202[01]) - 第1组(Series.str.extract的实际返回结果):1800到2021 (?!\d) - 右手数字边界

在这个具体的例子中,一个简单的

df['second_year'] = df['col'].str.extract(r'.*-(\d4)')

就足够了:任何文本(尽可能多的除换行符以外的字符),然后是 - 和捕获到第 1 组的四位数字。

见this regex demo。

【讨论】:

您好,非常感谢您的帮助 :) 我刚刚发现一些 raws 只有一个日期(例如:1937),而另一些则有一个特殊字符(例如:1937-?)。像这样的东西: .str.extract(r'(\d+)-) 可以在第一部分工作吗? @Gwen 只需使用df['second_year'] = df['col'].str.extract(r'.*\b(\d4)')。我看到你对这里的验证并不感兴趣。 抱歉,验证? @Gwen 您正在使用if data &gt;= 1800 and data &lt;= 2021 验证年份。 从昨天开始,阅读了您的回复,我改变了我对数据集的处理方法,我首先通过排除超过 1800 年的每一年并在另一端停止在 2021 年对其进行清理。所以我不再需要验证部分,我可以只使用 str.extract,这让我的代码更清晰【参考方案3】:

使用正则表达式从子短语中查找年份,然后将其拆分并索引第二年。您可以在数据框中使用它来申请分配给列

txt="firstname lastname (1937-2015)"
pattern='(\d4\-\d4)+'

matches=re.findall(pattern,txt)
print(matches[0].split('-')[1])

输出

2015

【讨论】:

以上是关于如何从 Python 中的文本中提取 2d 年?的主要内容,如果未能解决你的问题,请参考以下文章

Python元素树 - 从元素中提取文本,剥离标签

如何从python中的图像中删除某些文本?

JavaScript中如何提取字符串?

如何从python中的字符串中提取国家

如何提取XML文件中的数据?

如何从python中的字符串中提取月份和年份?