我想从Python中的数据框创建一个树形结构。 所需的输出看起来像这样:
{
"Cat1": {
"Band1" : {
"PE1": {
"1995-01": {
"GroupCalcs": {
"Count": 382.0,
"EqWghtRtn": -0.015839621267015727,
"Idx_EqWghtRtn": 0.9841603787329842,
"Idx_WghtRtn": 0.9759766819565102,
"WghtRtn": -0.02402331804348973
}
},
"1995-02": {
"GroupCalcs": {
"Count": 382.0,
"EqWghtRtn": -0.015839621267015727,
"Idx_EqWghtRtn": 0.9841603787329842,
"Idx_WghtRtn": 0.9759766819565102,
"WghtRtn": -0.02402331804348973
}
}
}
}
}
我正在寻找从Dataframe构建此方法的最有效方法。我有20k +行来解析当前看起来像这个片段
我在想这样的事情,但我知道这是非常低效的。
dctcat = {}
for cat in alldf.index.levels[0]:
dctMktBand = {}
for mktband in alldf.index.levels[1]:
dctpe = {}
for pe in alldf.index.levels[2]:
dctMonth = {}
for month in alldf.index.levels[3]:
dctMonth[month]=alldf.loc[[cat,mktband,pe,month]].filter(items=['Count', 'EqWghtRtn', 'Idx_EqWghtRtn','Idx_WghtRtn', 'WghtRtn']).to_dict()
dctpe[str(pe)]=dctMonth
dctMktBand[str(mktband)] = dctpe
dctcat[str(cat)] = dctpe
我偶然发现了这篇文章https://gist.github.com/hrldcpr/2012250并使用了defauldict(树),我能够在2秒内完成我所需要的。虽然听起来很长,但它比我的速度快得多。分享下面的代码,如果有人对此有更新或改进,我将不胜感激。
def tree():
return defaultdict(tree)
def dicts(t):
if isinstance(t ,defaultdict):
outval = {k: dicts(t[k]) for k in t }
else:
outval = t
return outval
alldf.set_index(['category','marketCapBand','peGreaterThanMarket','Month'], inplace=True)
tmp = alldf.filter(items=['Count', 'EqWghtRtn', 'Idx_EqWghtRtn','Idx_WghtRtn', 'WghtRtn']).to_dict('index')
outjson = tree()
for k,v in tmp.items():
(cat,mkb,pe,mon) = k
outjson[str(cat)][str(mkb)][str(pe)][str(mon)] = v
# convert back to dictionary
outjson = dicts(outjson)