我有一个清单:
data_list= [
{
'fields': {
'standard': ['ADSL1'],
'serviceCode': ['BNG_DSL'],
'deltaUpload': [0]
}
},
{
'fields': {
'standard': ['ADSL1'],
'serviceCode': ['BNG_DSL'],
'deltaUpload': [545618]
}
},
{
'fields': {
'standard': ['ADSL1'],
'serviceCode': ['BNG_DSL'],
'deltaUpload': [597561]
}
},
{
'fields': {
'standard': ['ADSL1'],
'serviceCode': ['BNG_DSL'],
'deltaUpload': [323771]
}
},
{
'fields': {
'standard': ['ADSL1'],
'serviceCode': ['BNG_DSL'],
'deltaUpload': [1088]
}
}
]从这个列表中,我创建了一个数据帧:

从df.fields系列中,我想创建一个新的数据帧。我试着这样做:

一切正常,但我不希望每个单元格都在列表中。我试过了:

...which可以工作,但由于有十亿分之一的数据行数,它的速度非常慢。有没有一种矢量化的方法可以在没有单元格列表的data_list中创建字段数据帧?
发布于 2020-01-16 22:37:06
您可以使用:
df = pd.DataFrame(data_list)
out = pd.DataFrame(df['fields'].tolist()).stack().str[0].unstack() standard serviceCode deltaUpload
0 ADSL1 BNG_DSL 0
1 ADSL1 BNG_DSL 545618
2 ADSL1 BNG_DSL 597561
3 ADSL1 BNG_DSL 323771
4 ADSL1 BNG_DSL 1088我们还可以尝试使用infer_objects推断正确的数据类型
out1 = (pd.DataFrame(df['fields'].tolist()).stack().str[0]
.astype(object).unstack().infer_objects())我们也可以直接做pd.io.json.json_normalize:
df = pd.io.json.json_normalize(data_list).rename(columns=lambda x: x.split('.')[1])
df.stack().str[0].astype(object).unstack().infer_objects()print(out.dtypes)
#standard object
#serviceCode object
#deltaUpload object
#dtype: object
print(out1.dtypes)
#standard object
#serviceCode object
#deltaUpload int64
dtype: object发布于 2020-01-17 13:18:42
pandas中的json_normalize函数并不是特别快。我建议您将初始数据缩减为列表或字典,然后创建数据帧:
d = [(i['fields']['standard'][0],
i['fields']['serviceCode'][0],
i['fields']['deltaUpload'][0])
if i['fields']['standard'] else ''
if i['fields']['serviceCode'] else ''
if i['fields']['deltaUpload'] else ''
for i in data_list ]
d
[('ADSL1', 'BNG_DSL', 0),
('ADSL1', 'BNG_DSL', 1088),
('ADSL1', 'BNG_DSL', 323771),
('ADSL1', 'BNG_DSL', 545618),
('ADSL1', 'BNG_DSL', 597561)]
df = pd.DataFrame(d)
df.columns = ['standard','serviceCode','deltaUpload']
standard serviceCode deltaUpload
0 ADSL1 BNG_DSL 545618
1 ADSL1 BNG_DSL 1088
2 ADSL1 BNG_DSL 323771
3 ADSL1 BNG_DSL 597561
4 ADSL1 BNG_DSL 0在我的PC上运行的时间: 596µs±14.7µs /循环(平均值±标准dev.共7次运行,每次1000次循环)。
随着时间的推移,我们学到了更多:更短的代码,更干净的代码:
from collections import defaultdict
d = defaultdict(list)
for entry in data_list:
for k,v in entry['fields'].items():
d[k].append(v[0])
pd.DataFrame(d)https://stackoverflow.com/questions/59771692
复制相似问题