Обработка векторизованного текста серии Pandas - PullRequest
0 голосов
/ 28 мая 2018

Я хотел бы улучшить свой код Pandas, используя векторизованные операции.Допустим, у меня есть простой DataFrame с одним текстовым столбцом, который может содержать URL.

       Column1
0  hello http://www.google.com
1  bye www.mail.com www.docs.google.com/index
   ...

В данный момент я перебираю строки и применяю следующую подстановку:

s = re.sub('https*://[\w\.]+\.com[\w=*/\-]+|https*://[\w\.]+\.com|[\w\.]+\.com/[\w/\-]+',lambda x: re.findall('(?<=\://)[\w\.]+\.com|[\w\.]+\.com', x.group())[0], s)

ожидаемый результат должен быть:

       Column1
0  hello google.com
1  bye mail.com docs.google.com
   ...

Возможно ли сделать это целыми сериями за раз?

Ответы [ 4 ]

0 голосов
/ 31 мая 2018

После многих ошибок я нашел правильное решение.Это далеко не эффективно, но в данный момент мне нужно что-то, что работает, я постараюсь оптимизировать это в ближайшем будущем и обновить пост.

def replace_url(text):
    pat = '(([https?://]*[www\.]*)([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?)'
    urls = re.findall(pat, text)

    for url in urls:
        text = text.replace(url[0], url[2])

    return text

df['Column1'] = df['Column1'].apply(replace_url)

Благодаря @ killerT2333 он дал мне некоторую интуицию о том, какпродолжить.

0 голосов
/ 28 мая 2018

Сохраняя свою логику и свой код для подстановки, вы можете сделать это следующим образом:

    import pandas as pd
    import re

    d = {'Column1': ["hello http://www.google.com", "bye www.mail.com www.docs.google.com/index"]}
    df = pd.DataFrame(data=d)


    f = lambda s : re.sub('https*://[\w\.]+\.com[\w=*/\-]+|https*://[\w\.]+\.com|[\w\.]+\.com/[\w/\-]+',lambda x: re.findall('(?<=\://)[\w\.]+\.com|[\w\.]+\.com', x.group())[0], s)


    print(df["Column1"].apply(f))
0 голосов
/ 30 мая 2018
import re

def replace_url(text):
    """
    Define the beginning of a url in a regex and replace any input text with an empty string using the regex
    INPUT: text (type = string)
    OUTPUT: text (type = string)
    """
    url_reg = re.compile(r"(http(s)?|www).*(\.)")
    return re.sub(url_reg, "", text)

df['Column1'] = df['Column1'].apply(replace_url)

Здесь у нас есть четко определенная функция (замените начало URL), затем мы применяем ее векторизованным способом ко всему столбцу кадра данных.Этот метод обычно быстрее, чем метод замены панд, хотя я здесь не рассчитал время, поэтому я не уверен в этом.

0 голосов
/ 28 мая 2018

с примером, который вы приводите, вы можете использовать str.replace():

df['column1'] = df['column1'].str.replace('http|https|://|www.','') \ 
                              #replace some patterm by nothing
                              .str.replace('.com/[\w/\-]+','.com') 
                              # replace specific pattern by other specific pattern

Тогда, если он не соответствует всем вашим критериям, вы можете добавить больше .str.replace() с тем, что вам нужно

РЕДАКТИРОВАТЬ: после просмотра документации Series.str.replace она эквивалентна re.sub(), поэтому вы можете сделать:

df['column1'] = df['column1'].str.replace('https*://[\w\.]+\.com[\w=*/\-]+|https*://[\w\.]+\.com|[\w\.]+\.com/[\w/\-]+',
                                          lambda x: re.findall('(?<=\://)[\w\.]+\.com|[\w\.]+\.com', x.group())[0])

Внутри параметры такие же, какв вашем re.sub() вашего вопроса.Но вы не получаете ожидаемый результат, вы сохраняете «www».с этим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...