#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