Создание кадра данных из списка списков: данные столбца, повторяющиеся для каждой записи - PullRequest
0 голосов
/ 19 февраля 2020

У меня есть список списков, которые я пытаюсь преобразовать в фрейм данных. Как следует из названия, каждая запись содержит имя столбца и значение. Вот модифицированный пример того, как выглядит мой список:

    sample_list =
        [['record',''],
        ['fname','John'],
        ['lname','Smith'],
        ['bdate','1985-06-15'],
        ['record',''],
        ['fname','Mary'],
        ['lname','Smith'],
        ['bdate','1990-03-12'],
                          ...]

Я из мира VBA, и я, вероятно, справлюсь с чем-то подобным с помощью al oop. Однако меня предупредили не делать этого для действительно больших наборов данных (случается, что это преобразование необходимо). Какой метод я должен использовать, чтобы дать мне следующий результат:

fname | lname | bdate
John  | Smith | 1985-06-15
Mary  | Smith | 1990-03-12
...

Любая помощь или указание в правильном направлении очень ценится.

Ответы [ 2 ]

1 голос
/ 19 февраля 2020

В этом стиле есть несколько возможных решений, я остановился на одном, который я считаю достойным. Я знаю, что вы сказали, что ввод довольно велик, и вы беспокоились о влиянии явного l oop, поэтому дайте мне знать, если это плохо.

import pandas as pd

raw_data = [['record', ''],
            ['fname', 'John'],
            ['lname', 'Smith'],
            ['bdate', '1985-06-15'],
            ['record', ''],
            ['fname', 'Mary'],
            ['lname', 'Smith'],
            ['bdate', '1990-03-12']]

# generates dictionaries mapping the column name to the value, for each record
rec_dicts = (dict(raw_data[i + 1:i + 4]) for i in range(0, len(raw_data), 4))

df = pd.DataFrame(rec_dicts)
df['bdate'] = pd.to_datetime(df['bdate'])

print(df)

Вывод:

  fname  lname      bdate
0  John  Smith 1985-06-15
1  Mary  Smith 1990-03-12

Вот решение, которое учитывает отсутствующие / разные данные в записях.

import pandas as pd

raw_data = [['record', ''],
            ['fname', 'John'],
            ['lname', 'Smith'],
            ['bdate', '1985-06-15'],
            ['other', 'a value'],
            ['record', ''],
            ['fname', 'Mary'],
            ['lname', 'Smith'],
            ['bdate', '1990-03-12']]

rec_dicts = []
curr_rec = {}

for curr_key, curr_val in raw_data:
    if curr_key == "record":
        rec_dicts.append(curr_rec)
        curr_rec = {}
    else:
        curr_rec[curr_key] = curr_val
rec_dicts.append(curr_rec)

if not rec_dicts[0]:
    rec_dicts = rec_dicts[1:]

print(rec_dicts, end='\n\n')

df = pd.DataFrame(data=rec_dicts)
df['bdate'] = pd.to_datetime(df['bdate'])

print(df)

Вывод:

[{'fname': 'John', 'lname': 'Smith', 'bdate': '1985-06-15', 'other': 'a value'}, {'fname': 'Mary', 'lname': 'Smith', 'bdate': '1990-03-12'}]

  fname  lname      bdate    other
0  John  Smith 1985-06-15  a value
1  Mary  Smith 1990-03-12      NaN

Как и в предыдущем методе, существует много возможные варианты. Какой из них лучше, будет зависеть от специфики вашей программы.

0 голосов
/ 19 февраля 2020

Вероятно, лучше всего перебрать данные, но это решение pandas с выводом pivot:

(pd.DataFrame(lst)
   .assign(group=lambda x: x[0].eq('record').cumsum())
   .pivot(index='group', columns=0, values=1)
   .drop('record', axis=1)
)

:

0           bdate fname  lname
group                         
1      1985-06-15  John  Smith
2      1990-03-12  Mary  Smith
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...