如何将具有不规则数据的多级字典转换为所需格式

How to convert Multilevel Dictionary with Irregular Data to Desired Format

Dict = {'Things' : {'Car':'Lambo', 'Home':'NatureVilla', 'Gadgets':{'Laptop':{'Programs':{'Data':'Excel', 'Officework': 'Word', 'Coding':{'Python':'PyCharm', 'Java':'Eclipse', 'Others': 'SublimeText'}, 'Wearables': 'SamsungGear', 'Smartphone': 'Nexus'}, 'clothes': 'ArmaaniSuit', 'Bags':'TravelBags'}}}}



d = {(i,j,k,l,m,n): Dict[i][j][k][l][m][n]
     for i in Dict.keys()
     for j in Dict[i].keys()
     for k in Dict[j].keys()
     for l in Dict[k].keys()
     for m in Dict[l].keys()
     for n in Dict[n].keys()
     }

mux = pd.MultiIndex.from_tuples(d.keys())
df = pd.DataFrame(list(d.values()), index=mux)
print (df)

我已经做过的事情: 我尝试使用 pandas 对这个不规则数据进行多索引,但我在 'Car' 处收到 KeyError。然后我尝试处理异常并尝试通过它,但随后导致语法错误。所以可能我迷失了方向。如果有任何其他模块或方式我可以索引这个不规则数据并以某种方式将它放在 table 中。我有一大块这样的原始数据。

我想做什么: 我想使用此数据在来自 PyQt5 的 QTableView 中进行打印(使用 GUI 制作程序)。

条件: 此数据从 API.

开始每小时更新一次

到目前为止我的想法: 也许我可以将所有这些数据附加到 MySQL。但是当这个数据从 API 更新时,只有 Values 会改变,其余的 KEYS 将是相同的。但随后它将需要更多 space.

参考文献:

任何帮助将不胜感激。感谢您阅读问题。

您的信息看起来很像 json,这就是 API 返回的内容。如果是这样,并且您正在将它变成一本字典,那么您最好使用 python 的 json 库,甚至是 panda 构建的 read_json 格式。

Pandas read json

Python's json

您的数据实际上不是您引用的 3 级示例中的字典那样的 6 级词典。不同之处在于:您的字典有多个不同级别的数据,例如'Lambo' 值位于层次结构的第二层,键为 ('Things','Car'),但 'Eclipse' 值位于层次结构的第六层,键为 ('Things','Gadgets','Laptop','Programs','Coding','Java')

如果您想 'flatten' 您的结构,您将需要决定如何处理 'missed' 键值以获得更深层次的值,例如 'Lambo'.

顺便说一句,也许它实际上不是您问题的解决方案,也许您需要使用更合适的 UI 小部件(如 TreeView)来处理此类分层数据,但我会尝试直接 准确回答您的问题

不幸的是,在一个简单的字典或列表理解语句中统一引用所有不同级别的值似乎并不容易。 只要看看你的 'value extractor' (Dict[i][j][k][l][m][n]) 就没有这样的 i、j、k、l、m、n 存在的值,这允许你得到一个 'Lambo'。因为要获得兰博,您只需要使用 Dict['Things']['Car'](具有讽刺意味的是,在现实生活中也很难获得兰博 :-))

解决任务的一种直接方法是: 提取二级数据,提取三级数据,依此类推,并将它们组合在一起。 例如。要提取二级值,您可以这样写:

val_level2 = {(k1,k2):Dict[k1][k2] 
   for k1 in Dict 
   for k2 in Dict[k1] 
   if isinstance(Dict[k1],dict) and 
      not isinstance(Dict[k1][k2],dict)}

但是如果你想稍后将它与六个级别的值结合起来,它需要向你的键元组添加一些填充:

val_level2 = {(k1,k2,'','','',''):Dict[k1][k2] 
   for k1 in Dict 
   for k2 in Dict[k1] 
   if isinstance(Dict[k1],dict) and 
      not isinstance(Dict[k1][k2],dict)}

稍后您可以通过以下方式将所有内容组合在一起:

d = {}
d.update(val_level2)
d.update(val_level3)

但通常处理分层数据的最有机方法是使用一些递归,如下所示:

def flatten_dict(d,key_prefix,max_deep):
    return [(tuple(key_prefix+[k]+['']*(max_deep-len(key_prefix))),v) 
        for k,v in d.items() if not isinstance(v,dict)] +\
        sum([flatten_dict(v,key_prefix+[k],max_deep) 
              for k,v in d.items() if isinstance(v,dict)],[])

然后用这样的代码:

d={k:v for k,v in flatten_dict(Dict,[],5)}
mux = pd.MultiIndex.from_tuples(d.keys())
df = pd.DataFrame(list(d.values()), index=mux)
df.reset_index()

我实际上用你的数据得到了这个结果:

P.S。根据 https://www.python.org/dev/peps/pep-0008/#prescriptive-naming-conventions 我们更喜欢 lowercase_with_underscores 作为变量名,CapWords 是 类。所以 src_dict 会比你的情况下的 Dict 好得多。