以下是我正在使用的实际dict
的简化示例。转储到JSON文件时,实际的dict
非常大(大约10 MB)。我正在尝试通过字典解析并将其转换为使用特定格式的数据框。目的是使用to_excel
方法将此数据帧转储到excel中。
import pandas as pd
data = {'kvk_1':
{'link_1':
{'header_1':
{'body_1':'value_1',
'body_2':'value_2',
'body_3':'value_3'},
'header_2':
{'body_4':'value_1',
'body_4':'value_3',
'body_5':'value_2'}
},
'link_2':
{'header_4':
{'body_7':'value_8',
'body_8':'value_9'},
'header_2':
{'body_4':'value_6',
'body_4':'value_35',
'body_5':'value_25',
'body_6':'value_25'},
'header_3':
{}}},
'kvk_2':
{'link_1':
{'header_1':
{'body_1':'value_1',
'body_2':'value_2',
'body_3':'value_3'},
'header_2':
{'body_4':'value_1',
'body_4':'value_3',
'body_5':'value_2'},
'header_9':
{'body_10':'value_2'}
},
'link_2':
{'header_1':
{'body_2':'value_8',
'body_3':'value_9'},
'header_2':
{'body_6':'value_6',
'body_6':'value_35',
'body_5':'value_25',
'body_6':'value_25'},
'header_3':
{'body_9':'value_800'}},
'link_3': {}},
'kvk_3':
{'link_1':
{'header_10':{}}}}
#Write data
df = pd.DataFrame(columns = ['kvk', 'link'])
row = -1
for kvk, link_dict in data.items():
for link, header_dict in link_dict.items():
row = row+1
df.loc[row, 'kvk'] = kvk
df.loc[row, 'link'] = link
for header, body_dict in header_dict.items():
for body, value in body_dict.items():
df.loc[row, body] = value
哪个输出以下pandas
数据帧:
kvk link body_1 body_2 body_3 body_4 body_5 body_7 \
0 kvk_1 link_1 value_1 value_2 value_3 value_3 value_2 NaN
1 kvk_1 link_2 NaN NaN NaN value_35 value_25 value_8
2 kvk_2 link_1 value_1 value_2 value_3 value_3 value_2 NaN
3 kvk_2 link_2 NaN value_8 value_9 NaN value_25 NaN
4 kvk_2 link_3 NaN NaN NaN NaN NaN NaN
5 kvk_3 link_1 NaN NaN NaN NaN NaN NaN
body_8 body_6 body_10 body_9
0 NaN NaN NaN NaN
1 value_9 value_25 NaN NaN
2 NaN NaN value_2 NaN
3 NaN value_25 NaN value_800
4 NaN NaN NaN NaN
5 NaN NaN NaN NaN
对于实际情况,这非常慢。我认为瓶颈是最后一行df.loc[row, body] = value
,其中pandas
需要根据dict
键和递增的行号在不断增长的数据框中定位一个单元格。如果键指向的列存在,则添加新行并将值插入该行。如果该列不存在,则会创建一个新列并插入值。
我真的很喜欢这种设置,因为它允许我按名称查找列,这对于dict的设置非常理想。但是,正如我已经提到的,当数据帧超过大约10000行时,它停止运行。我该如何调整以加快速度?
谢谢
答案 0 :(得分:4)
首先使用循环为字典列表更改数据的结构:
out = []
for k, v in data.items():
for k1, v1 in v.items():
d = {}
for k2, v3 in v1.items():
d.update(v3)
out.append({**d, **{'kvk':k, 'link':k1}})
#print (out)
df = pd.DataFrame(out)
cols = ['kvk','link']
#if want cols for first columns in df and sorting body columns by numbers after _
c = cols + sorted(df.columns.difference(cols), key=lambda x: int(x.split('_')[1]))
#if need only change order by ['kvk','link']
#c = cols + df.columns.difference(cols).tolist()
df = df[c]
print (df)
kvk link body_1 body_2 body_3 body_4 body_5 body_6 \
0 kvk_1 link_1 value_1 value_2 value_3 value_3 value_2 NaN
1 kvk_1 link_2 NaN NaN NaN value_35 value_25 value_25
2 kvk_2 link_1 value_1 value_2 value_3 value_3 value_2 NaN
3 kvk_2 link_2 NaN value_8 value_9 NaN value_25 value_25
4 kvk_2 link_3 NaN NaN NaN NaN NaN NaN
5 kvk_3 link_1 NaN NaN NaN NaN NaN NaN
body_7 body_8 body_9 body_10
0 NaN NaN NaN NaN
1 value_8 value_9 NaN NaN
2 NaN NaN NaN value_2
3 NaN NaN value_800 NaN
4 NaN NaN NaN NaN
5 NaN NaN NaN NaN