Как создать фрейм данных из списка строк с различным количеством атрибутов на строку

#python #regex #pandas #dataframe #data-structures

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

Вопрос:

Допустим, у меня есть список строк, где каждая запись имеет переменное количество «атрибутов» и где порядок может отличаться из-за этого.

 str_list = ['id1 [first="jake" last="sully" hours="24"]',
            'id2 [first="bob" last="ross" job="painter" hours="11]']
  

Как я могу превратить этот список в фрейм данных, где, если в строке отсутствует атрибут, он будет просто пустым в df?

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

    id   first        job     last    hours
  id1    jake               sully       24 
  id2     bob    painter     ross       11
  

Я знаю, что для id я могу просто разделить строку на ‘[‘ и получить 0-й индекс, так что это не проблема.
Для получения элементов атрибутов из строковой записи я знаю, что могу просто использовать

 test_list = re.findall(r'"(.*?)"', str)
  

чтобы получить список значений, но как я мог бы использовать это для достижения моей всеобъемлющей цели с различным количеством «атрибутов» / беспорядочного порядка в каждой записи?

Ответ №1:

Попробуйте это:

 import re
import pandas as pd

str_list = ['id1 [first="jake" last="sully" hours="24"]', 'id2 [first="bob" last="ross" job="painter" hours="11"]']

res = []
for item in str_list:
    current = {'id': re.findall('idd ', item)[0]}
    for col in ['first', 'last', 'job', 'hours']:
        x = re.findall(f'{col}="(.*?)"', item)
        if x :
            current[col] = x[0]
            
    res.append(current)

pd.DataFrame(res)
  

Вывод:

     id first   last hours      job
0  id1  jake  sully    24      NaN
1  id2   bob   ross    11  painter
  

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

1. есть ли способ сохранить его в порядке, не переупорядочивая его вручную после?

2. мы можем изменить порядок столбцов после создания фрейма данных, dict неупорядочен

3. можете ли вы объяснить, что current = {'id': re.findall('idd ', item)[0]} делает? а также x = re.findall(f'{col}="(.*?)"', item)