Почему регулярное выражение дает мне None, когда шаблон на самом деле существует - PullRequest
0 голосов
/ 05 марта 2020

Я пытаюсь извлечь имена из текста Твиттера с помощью регулярных выражений. Но, несмотря на шаблон, возвращаемое значение равно none, что не совсем так. Где мой код не так, я понятия не имею. Я использую jupyter lab.

Пример текста: pd.Series full_text

0    RT @SeamusHughes: The Taliban Stamp of approva...
1    RT @WFaqiri: Taliban and Afghan groups find co...
2    RT @DavidCornDC: Imagine what Fox News would h...
3    RT @DavidCornDC: Imagine what Fox News would h...
4    RT @billroggio: Even if you are inclined to tr...
5    RT @billroggio: I am sure we will hear the arg...
6    RT @KFILE: This did happen and it went exactly...
Name: full_text, dtype: object

Моя функция определена следующим образом:

def extract_user(text):
        m = re.search(r"RT\s@\w+:", text)
        return m  

И я применяю вышеуказанная функция, как показано ниже:

full_text.apply(extract_user)

Но значения, которые я получаю взамен, следующие:

0        None
1        None
2        None
3        None
4        None
         ... 
21299    None
21300    None
21301    None
21302    None
21303    None
Name: full_text, Length: 21304, dtype: object

Ответы [ 3 ]

1 голос
/ 05 марта 2020

Как насчет чего-то подобного, используя лямбда-функцию внутри него:

>>> df[0].apply(lambda text: re.search(r'RT\s@([^:]+)',text).group(1))
0    SeamusHughes
1         WFaqiri
2     DavidCornDC
3     DavidCornDC
4      billroggio
5      billroggio
6           KFILE

И собрав все это вместе для тщательности:

import pandas as pd
data = [['RT @SeamusHughes: The Taliban Stamp of approva...'],['RT @WFaqiri: Taliban and Afghan groups find co...'],['RT @DavidCornDC: Imagine what Fox News would h...'],['RT @DavidCornDC: Imagine what Fox News would h...'],['RT @billroggio: Even if you are inclined to tr...'],['RT @billroggio: I am sure we will hear the arg...'],['RT @KFILE: This did happen and it went exactly...']]
df=pd.DataFrame(data)
df[0].apply(lambda text: re.search(r'RT\s@([^:]+)',text).group(1))

# 0    SeamusHughes
# 1         WFaqiri
# 2     DavidCornDC
# 3     DavidCornDC
# 4      billroggio
# 5      billroggio
# 6           KFILE
# Name: 0, dtype: object
1 голос
/ 05 марта 2020

Причина, по которой это происходит, заключается в том, что ваша функция (extract_user) возвращает:

0    <re.Match object; span=(5, 22), match='RT @Sea...
1    <re.Match object; span=(5, 17), match='RT @WFa...
2    <re.Match object; span=(5, 21), match='RT @Dav...
3    ...

Теперь я не эксперт, поэтому возьмите это с крошкой соли, но я думаю, что pandas не имеет dtype для обработки <re.Match> объекта, который возвращает ваша функция, и поэтому обрабатывает его с помощью None. Проверьте этот отличный ответ, если вы хотите глубже погрузиться в обработанные dtypes.

Итак, если вы хотите, чтобы все ваши подходы были одинаковыми с минимальными изменениями, вот пример вашего функция модифицируется простым возвращением первого элемента ([0]) каждого <re.Match> объекта.

def extract_user(text):
         m = re.search(r"RT\s@\w+:", text)
         return m[0]                        # <-- here

stuff = df.iloc[:, 0].apply(extract_user)

print(stuff)

0    RT @SeamusHughes:
1         RT @WFaqiri:
2     RT @DavidCornDC:
3     RT @DavidCornDC:
4      RT @billroggio:
5      RT @billroggio:
6           RT @KFILE:

Надеюсь, что все прояснит.

1 голос
/ 05 марта 2020

Вы можете сделать намного проще с кодом ниже

df.A.str.extract(r"(@\w+)") #A is the column name

Выход

    0
0   @SeamusHughes
1   @WFaqiri
2   @DavidCornDC
3   @DavidCornDC
4   @billroggio
5   @billroggio
6   @KFILE

Если вы хотите только имена, а не @ символ, используйте df.A.str.extract(r"@(\w+)")

Выход

    0
0   SeamusHughes
1   WFaqiri
2   DavidCornDC
3   DavidCornDC
4   billroggio
5   billroggio
6   KFILE
...