Python создает новый столбец с извлеченным регулярным выражением до n из фрейма данных

#python #regex #pandas #dataframe #extract

Вопрос:

У меня есть фрейм данных, подобный приведенному ниже:

 data = {'c1':['Level:     LOGGING_ONLYn Thrown: lib: this is problem type 01n tn tError executing the statement: error statement 1n', 
              'Level: NOT_LOGGING_ONLYn Thrown: lib: this is problem type 01n tn tError executing the statement: error statement 3n', 
              'Level:     LOGGING_ONLYn Thrown: lib: this is problem type 02n tn tError executing the statement: error statement2n', 
              'Level: NOT_LOGGING_ONLYn Thrown: lib: this is problem type 04n tn tError executing the statement: error statement1n'],
        'c2':["one", "two", "three", "four"]}
 

Я хотел бы создать:

  • регулярное выражение, которое извлекает что-либо после Thrown: lib: до первого n . Я буду называть это «группа 01». Поэтому у меня будет это ниже:
     data = {'c3':['this is problem type 01', 
                   'this is problem type 01', 
                   'this is problem type 02', 
                   'this is problem type 04']}
     
  • а затем я хочу создать регулярное выражение, которое извлекает все после «группы 01″(предыдущее регулярное выражение), игнорируя t и n , что находится между предложениями, и переходя к следующему n . Поэтому у меня будет это ниже:
     data = {'c4':['Error executing the statement: error statement 1', 
                'Error executing the statement: error statement 3', 
                'Error executing the statement: error statement2', 
                'Error executing the statement: error statement1']}
     

В конце концов, я хочу, чтобы мой фрейм данных был таким:

 data = {'c1':['Level:     LOGGING_ONLYn Thrown: lib: this is problem type 01n tn tError executing the statement: error statement 1', 
              'Level: NOT_LOGGING_ONLYn Thrown: lib: this is problem type 01n tn tError executing the statement: error statement 3', 
              'Level:     LOGGING_ONLYn Thrown: lib: this is problem type 02n tn tError executing the statement: error statement2', 
              'Level: NOT_LOGGING_ONLYn Thrown: lib: this is problem type 04n tn tError executing the statement: error statement1'],
        'c3':['this is problem type 01', 
              'this is problem type 01', 
              'this is problem type 02', 
              'this is problem type 04'],
        'c4':['Error executing the statement: error statement 1', 
              'Error executing the statement: error statement 3', 
              'Error executing the statement: error statement2', 
              'Error executing the statement: error statement1'],
        'c2':["one", "two", "three", "four"]}
 

Это то, что я до сих пор пытался извлечь из « Thrown: lib: » до первого n , но это не работает.

 df = pd.DataFrame(data)
df['exception'] = df['c1'].str.extract(r'Thrown: lib: (.*(?:r?n.*)*)', expand=False)
 

Ответ №1:

Вероятно, можно было бы сделать это как однострочный, но что-то вроде этого:

 import re
import pandas as pd


data = {'c1':['Level:     LOGGING_ONLYn Thrown: lib: this is problem type 01n tn tError executing the statement: error statement 1n', 
              'Level: NOT_LOGGING_ONLYn Thrown: lib: this is problem type 01n tn tError executing the statement: error statement 3n', 
              'Level:     LOGGING_ONLYn Thrown: lib: this is problem type 02n tn tError executing the statement: error statement2n', 
              'Level: NOT_LOGGING_ONLYn Thrown: lib: this is problem type 04n tn tError executing the statement: error statement1n'],
        'c2':["one", "two", "three", "four"]}



df = pd.DataFrame(data)

pattern1 = 'Thrown: lib: ([a-zA-Zds]*)\n'
df['c3'] = df['c1'].str.extract(pattern1, expand=False).str.strip()

pattern2 = '(\ns\t){1,}(.*)\n'
df['c4'] = df['c1'].str.extract(pattern2, expand=True)[1]
 

Выход:

 print(df.to_string())
                                                                                                                           c1     c2                       c3                                                c4
0  Level:     LOGGING_ONLYn Thrown: lib: this is problem type 01n tn tError executing the statement: error statement 1n    one  this is problem type 01  Error executing the statement: error statement 1
1  Level: NOT_LOGGING_ONLYn Thrown: lib: this is problem type 01n tn tError executing the statement: error statement 3n    two  this is problem type 01  Error executing the statement: error statement 3
2   Level:     LOGGING_ONLYn Thrown: lib: this is problem type 02n tn tError executing the statement: error statement2n  three  this is problem type 02   Error executing the statement: error statement2
3   Level: NOT_LOGGING_ONLYn Thrown: lib: this is problem type 04n tn tError executing the statement: error statement1n   four  this is problem type 04   Error executing the statement: error statement1
 

Комментарии:

1. Здравствуйте, здравствуйте, спасибо за обновление! Я не понял вашего регулярного выражения, но, думаю, оно не сработало, когда я тестировал. Например, c4-это то, что вы сказали, более того, это должно быть после «группы 01», как я написал в первоначальном вопросе. Это означает, что он должен иметь разделитель n tn сразу после «Thrown: lib:» для работы, в противном случае будет соответствовать n tn, которые существовали до «группы 01″. (мне нужен первый n tn сразу после » Брошено: lib:») 🙂

2. Я смог изменить ваш второй шаблон, чтобы сделать то, что я хотел, вот так: pattern 2 = ‘Брошено: lib.gack. GackContext: [^n] (\ns\t){1,}(.*)\н. Спасибо 🙂

3. Не могли бы вы объяснить вторую закономерность? Я смог изменить это путем проб и ошибок, но я буду рад лучше понять регулярное выражение 🙂

Ответ №2:

Я бы использовал re пакет:

 data['c3'] = [re.findall("Thrown: lib: ([^n] )", x) for x in data['c1']]
data['c4'] = [re.split("n", x)[3].strip() for x in data['c1']]
 
  • Первый шаблон извлекает все, что находится между Thrown: lib: и первой новой строкой
  • второй шаблон предполагает, что соответствующее сообщение всегда является 4-м маркером , если разделить его на n , что, по-видимому, имеет место

ПРОДОЛЖЕНИЕ: следующий вопрос ниже. Шаблон для data['c4'] основан на том факте, что сообщение всегда находится после 4 « n » новых строк в сообщении.
Теперь, если разделителем, представляющим интерес, является» n tn «, вы можете изменить шаблон в:

 data['c4'] = [re.split("n tn", x)[1].strip() for x in data['c1']]
 

или

 data['c4'] = [re.findall(".*?n tn(.*)", x)[0].strip() for x in data['c1']]
 

Последний подход лучше, учитывая, что, если split произойдет сбой на разделителе, вы получите IndexError .

Комментарии:

1. Привет! Спасибо за ответ! Получил первый шаблон, он работает 🙂 Более того, второй-после «n tn t», а не только после «n». У вас есть какие-нибудь советы о том, как измениться, чтобы принять это? 🙂