Текст регулярного выражения во фрейм данных pandas

#python #regex #pandas

#python #регулярное выражение #pandas

Вопрос:

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

 real    0m0.020s
user    0m0.000s
sys 0m0.000s
Round  1  completed. with matrix size of  1200 x 1200 with threads 8

real    0m0.022s
user    0m0.000s
sys 0m0.001s
Round  2  completed. with matrix size of  1200 x 1200 with threads 8
  

Существует около 500 записей такого рода (выше приведен пример из 2). Кажется, я не могу понять, как поместить их в фрейм данных pandas, который может выглядеть примерно так:

 Matrix Size    Threads    Round    Real    User    Sys
1200 x 1200    8          1        0.0020  0.0000  0.0000
1200 x 1200    8          2        0.0022  0.0000  0.0001
  

Есть ли способ с использованием регулярных выражений или каким-либо другим способом преобразовать выходные данные теста в фрейм данных. Кроме того, я не знаю, правильно ли я интерпретировал время, поскольку они находятся в 0m (я думаю, 0 минут) и 0.02 (я думаю, 0.02 секунды)

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

1. Всегда ли существуют две новые строки между блоками, каждый из которых будет формировать строку фрейма данных?

2. Бьюсь об заклад, что времени, которое вы задаете этот вопрос и ждете ответа, вам достаточно, чтобы создать и запустить простое решение цикла for для этих 500 записей 🙂

3. Да, каждый блок будет формировать запись, и между ними будет две новые строки

Ответ №1:

Вы можете использовать регулярное выражение:

 import re
import pandas as pd

regex = re.compile(r'real  (dmd.d s)nuser  (dmd.d s)nsys  (dmd.d s)nRound  (d ). of  (d  x d ). threads (d )')

df = pd.DataFrame(regex.findall(data), columns=['real', 'user', 'sys', 'round', 'matrix size', 'threads'])

print(df)
  

Вывод:

        real      user       sys round  matrix size threads
0  0m0.020s  0m0.000s  0m0.000s     1  1200 x 1200       8
1  0m0.022s  0m0.000s  0m0.001s     2  1200 x 1200       8
  

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

1. Есть ли способ, которым я мог бы преобразовать 0m0.020s в (0 * 60) [из m] (0.020) [из s]

2. @user9996043 Как насчет df['real'].str.replace('s', '').str.split('m').map(lambda t: float(t[0]) * 60 float(t[1])) ?

Ответ №2:

Если вы хотите решить проблему, используя только pandas вы можете использовать str.split() :

 # data
s = """real    0m0.020s
user    0m0.000s
sys 0m0.000s
Round  1  completed. with matrix size of  1200 x 1200 with threads 8

real    0m0.022s
user    0m0.000s
sys 0m0.001s
Round  2  completed. with matrix size of  1200 x 1200 with threads 8"""

# str.split on two line breaks for rows then split on the text
df = pd.DataFrame(s.split('nn'))[0].str.split('   |real | with |user    |sys |matrix size of  |threads |n')
                                  .apply(lambda x: [s for s in x if s]).apply(pd.Series)

# split col 3 on round and completed to get number of rounds
df[3] = df[3].str.strip('Round | completed.')

# rename columns
df.columns = ['real', 'user', 'sys', 'round', 'matrix size', 'threads']
  

выход

        real      user       sys round  matrix size threads
0  0m0.020s  0m0.000s  0m0.000s     1  1200 x 1200       8
1  0m0.022s  0m0.000s  0m0.001s     2  1200 x 1200       8
  

обратите внимание, что это будет медленнее, пример gmds:

1000 loops, best of 3: 4.42 ms per loop против 1000 loops, best of 3: 1.84 ms per loop