我必须回答以下问题。有没有一种方法可以从python Generator对象列表中构建DataFrame。我使用列表推导来创建带有数据框数据的列表:
data_list.append([record.Timestamp,record.Value, record.Name, record.desc] for record in records)
我这样做是因为普通列表在for循环中附加的时间是原来的20倍:
for record in records:
data_list.append(record.Timestamp,record.Value, record.Name, record.desc)
我尝试创建数据框,但是它不起作用:
此:
dataframe = pd.DataFrame(data_list, columns=['timestamp', 'value', 'name', 'desc'])
抛出异常:
ValueError:已传递4列,所传递的数据具有142538列。
我也尝试过使用itertools这样:
dataframe = pd.DataFrame(data=([list(elem) for elem in itt.chain.from_iterable(data_list)]), columns=['timestamp', 'value', 'name', 'desc'])
此结果为空的DataFrame:
空数据帧\ n列:[时间戳,值,名称,描述] \ n索引:[]
数据列表看起来像这样:
[<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)
这是必需的,因为事件列表数据结构。
我是否有办法从Generator列表之外创建数据框?如果有,那将节省时间吗?我的意思是,我用列表理解替换了普通的for循环,节省了很多时间,但是,如果创建数据框需要更多时间,则此操作将毫无意义。
也只需将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条记录的生成器(我想是)。熊猫将尝试将您的data_list
中的单个条目填充到一行中(因此所有142538条目,每个包含四个元素的列表)都会失败,因为它希望传递4列。
import pandas as pd
import ast
# Method-1: create a dict by direct declaration
d = {
'timestamp': record.Timestamp,
'value': record.Value,
'name': record.Name,
'desc': record.desc,
}
# Method-2: create a dict using dict-comprehension
keys = ['Timestamp', 'Value', 'Name', 'desc']
d = dict((str(key).lower(), ast.literal_eval(f'record.{key}')) for key in keys)
dataframe = pd.DataFrame(d)