Создать Pandas Dataframe из списка генераторов - PullRequest
0 голосов
/ 02 марта 2020

У меня следующий вопрос. Есть ли способ построить DataFrame из списка python Генератор объектов. Я использовал понимание списка, чтобы создать список с данными для фрейма данных:

data_list.append([record.Timestamp,record.Value, record.Name, record.desc] for record in records)

Я сделал это так, потому что нормальное добавление списка в a для l oop занимает примерно в 20 раз больше:

for record in records:
    data_list.append(record.Timestamp,record.Value, record.Name, record.desc)

Я пытался создать фрейм данных, но он не работает:

This:

dataframe = pd.DataFrame(data_list, columns=['timestamp', 'value', 'name', 'desc'])

Исключение выдает:

Ошибка значения: 4 Переданные столбцы, переданные данные имеют 142538 столбцов.

Я также пытался использовать itertools следующим образом:

dataframe = pd.DataFrame(data=([list(elem) for elem in itt.chain.from_iterable(data_list)]), columns=['timestamp', 'value', 'name', 'desc'])

В результате получается пустой DataFrame:

Пустой DataFrame \ nColumns: [отметка времени, значение, имя, desc] \ nIndex: []

data_list выглядит так:

[<generator object St...51DB0>, <generator object St...56EB8>,<generator object St...51F10>, <generator object St...51F68>]

Код для создания списка выглядит как это:

for events in events_list:
    for record in events:
        data_list.append([record.Timestamp,record.Value, record.Name, record.desc] for record in records)

Это необходимо из-за структуры данных списка событий.

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

Ответы [ 3 ]

1 голос
/ 02 марта 2020

Просто превратите ваш data_list в выражение генератора. Например:

from collections import namedtuple

MyData = namedtuple("MyData", ["a"])
data = (d.a for d in (MyData(i) for i in range(100)))
df = pd.DataFrame(data)

будет работать просто отлично. Итак, что вы должны сделать, это иметь:

data = ((record.Timestamp,record.Value, record.Name, record.desc) for record in records)
df = pd.DataFrame(data, columns=["Timestamp", "Value", "Name", "Desc"])

Реальная причина, по которой ваш подход не работает, состоит в том, что у вас есть одна запись в вашем data_list, которая является генератором над - я предполагаю - 142538 записями. Pandas попытается втиснуть эту единственную запись в вашем data_list в одну строку (таким образом, все записи 142538, каждая из которых содержит список из четырех элементов) и завершится неудачей, поскольку ожидает, что будет передано скорее 4 столбца.

Редактировать: вы, конечно, можете сделать выражение генератора более сложным, вот пример в соответствии с вашими дополнительными событиями l oop over:

from collections import namedtuple
MyData = namedtuple("MyData", ["a", "b"])
data = ((d.a, d.b) for j in range(100) for d in (MyData(j, j+i) for i in range(100)))
pd.DataFrame(data, columns=["a", "b"])

edit: вот также пример с использованием таких структур данных, как Вы используете:

Record = namedtuple("Record", ["Timestamp", "Value", "Name", "desc"])

event_list = [[Record(Timestamp=1, Value=1, Name=1, desc=1),
               Record(Timestamp=2, Value=2, Name=2, desc=2)],
              [Record(Timestamp=3, Value=3, Name=3, desc=3)]]

data = ((r.Timestamp, r.Value, r.Name, r.desc) for events in event_list for r in events)
pd.DataFrame(data, columns=["timestamp", "value", "name", "desc"])

Вывод:

    timestamp   value   name    desc
0   1   1   1   1
1   2   2   2   2
2   3   3   3   3
0 голосов
/ 02 марта 2020

pd.concat(some_generator_yielding_dfs) будет работать (на самом деле это один из приемов, облегчающих загрузку больших таблиц). Например, можно сделать так:

pd.concat((pd.read_csv(x) for x in files))
0 голосов
/ 02 марта 2020

Решение

  • Создайте dict с нужными вам столбцами, как показано ниже.
  • Подайте данные в pandas .Датафрейм

Примечание : при использовании list(generator) все данные отображаются как list.

import pandas as pd
import ast

# Method-1: create a dict by direct declaration
d = {
    'timestamp': list(record.Timestamp),
    'value': list(record.Value),
    'name': list(record.Name), 
    'desc': list(record.desc), 
}

# Method-2: create a dict using dict-comprehension
keys = ['Timestamp', 'Value', 'Name', 'desc']
d = dict((str(key).lower(), ast.literal_eval(f'list(record.{key})')) for key in keys)

# Finally create the dataframe using the dictionary
dataframe = pd.DataFrame(d).T

См. Также :

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...