如何从 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)
- .
现在跨行匹配
(?<!\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 >= 1800 and data <= 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 年?的主要内容,如果未能解决你的问题,请参考以下文章