从列中提取 'year'

Extracting 'year' from a column

我有一个工作代码,但我认为我的逻辑不正确(尽管它有效)。我只需要一些帮助来优化它。本质上,看看我所做的是否是我正在做的事情的可接受方式,或者是否有更好的方式。我支持后者,因为我知道我所做的不是“正确”的方式。

我有一个 pd 字符串列,其中包含“年份”,我正在尝试从中提取它。问题是一些条目没有列出年份。所以像这样:

Index string_values
0 String A (1995)
1 String B (1995)
2 String C (1995)
3 String D has no year
4 String E has (something in braces) AND also the year (2003)

re.search('\d{4}', df['string_values '][0]).group(0) 有效,但在 for 循环中,它会抛出此错误(我想当它命中非 4 位字符串时):AttributeError: 'NoneType' object has no attribute 'group'。我认为这是因为 len(_temp) 给出 15036 并且它列出了 。只是它抛出了这个错误。

这是 for 循环:

_temp = []
for i in df['string_values']:
    year = re.search("\d{4}", i)
    if year.group():
        _temp.append(year.group())
    else:
        _temp.append(None)

然后我也尝试了 Try-Except 方法来做到这一点,并且有效 - len(<var>) 给出 62423,这也是 df 中的总行。这是代码:

_without_year = []
_with_year = []
for i in df['string_values']:
    year = re.search("\d{4}", i)
    try:
        if year.group():
            # _with_year.append(year.group())
            pass
    except:
        _without_year.append(i)

我只需要知道我所做的是否可以接受。它有效,就像我说的。 _without_year 会显示所有没有年份的条目。

Try-Except 块的问题是我 passif 条件下捕获第 i 个错误。

您可以使用extract直接提取年份值:

df['string_values'].str.extract(r'(?<=\()(\d{4})(?=\))', expand=False)

输出:

0    1995
1    1995
2    1995
3     NaN
4    2003
Name: string_values, dtype: object

请注意,我使用向前和向后环视来断言年份出现在括号内;如果您不想要它,而只是为了匹配一个 4 位数的字符串,请将它们替换为 \b(分词),例如

df['string_values'].str.extract(r'\b(\d{4})\b', expand=False)

要将输出转换为列表,可以使用tolist:

df['string_values'].str.extract('(?<=\()(\d{4})(?=\))', expand=False).tolist()

输出:

['1995', '1995', '1995', nan, '2003']

要查找不包含年份的字符串值,您可以使用 contains 查找匹配项并将其反转以用作索引:

df[~df['string_values'].str.contains(r'(?<=\()\d{4}(?=\))')]

输出:

   Index          string_values
3       3  String D has no year