Python 如何将pandas dataframe转换为结构独特的嵌套json

Python 如何将pandas dataframe转换为结构独特的嵌套json,python,json,pandas,dataframe,Python,Json,Pandas,Dataframe,我有一个DF,其结构如下: traffic_group app_id key category factors 0 desktop app1 CI html 16.618628 1 desktop app1 CI xhr 35.497082 2 desktop app1 IP html 18.294468 3 desktop ap

我有一个DF,其结构如下:

    traffic_group   app_id  key category    factors
0   desktop         app1    CI  html        16.618628
1   desktop         app1    CI  xhr         35.497082
2   desktop         app1    IP  html        18.294468
3   desktop         app1    IP  xhr         30.422464
4   desktop         app2    CI  html        11.028240
5   desktop         app2    CI  json        33.548279
6   mobile          app1    IP  html        12.808367
7   mobile          app1    IP  image       14.410633
我需要将其输出到以下结构的json:

{ "desktop": {
          app1: [ {
              "key": "CI",
              "threshold: 1,
              "window": 60,
              "factors: {
                   "html" : 16.618628
                   "xhr" : 35.497082
                        }
                  }, {
              "key": "IP",
              "threshold: 1,
              "window": 60,
              "factors: {
                   "html" : 18.294468
                   "xhr" : 30.422464
                        } 
                  ],
           app2: [ {
              "key": "CI",
              "threshold: 1,
              "window": 60,
              "factors: {
                   "html" : 11.028240
                   "json" : 33.548279
                        }
                  }
              },
  "mobile": {
          app1: [  {
              "key": "IP",
              "threshold: 1,
              "window": 60,
              "factors: {
                   "html" : 12.808367
                   "xhr" : 14.410633
                        } 
                 ]
             }
 } 
这一结构无疑是错综复杂的

我考虑了以下先前的答案,并试图模仿它们的逻辑,但没有效果:

感谢您的帮助。请不要只是发布解决方案,还要解释你的逻辑。

好吧,我已经用“老式”的方式解决了。为将来可能需要我的解决方案的任何人发布我的解决方案。尽管如此,如果有人能用熊猫做这件事,我很想看看

json_output = {}
for traffic_group in sorted_df.traffic_group.unique():
    json_output[traffic_group] = {}
    for app_id in sorted_df[sorted_df.traffic_group == traffic_group].app_id.unique():
        json_output[traffic_group][app_id] = []
        for key in sorted_df[(sorted_df.traffic_group == traffic_group) &
                             (sorted_df.app_id == app_id)].key.unique():
            inner_dict = {"key" : key, "threshold" : 1, "window" : 60, "factors" : {}}
            for category in sorted_df[(sorted_df.traffic_group == traffic_group) & 
                                      (sorted_df.app_id == app_id) & 
                                      (sorted_df.key == key)].category.unique():
                value = sorted_df[(sorted_df.traffic_group == traffic_group) & 
                                  (sorted_df.app_id == app_id) & 
                                  (sorted_df.key == key) & 
                                  (sorted_df.category == category)].factors  
                inner_dict["factors"][category] = value.iloc[0]
            json_output[traffic_group][app_id].append(inner_dict)
我在输入中没有看到嵌套字典的任何“阈值”和“窗口”键。假设它们有固定的值。根据您的输出,似乎每个三元组(流量组、应用程序id、密钥)都希望(通常)创建一个不同的嵌套字典。因此,我们需要使用这三个键进行初始groupby操作。我们为每个组创建嵌套字典:

def创建嵌套命令(df):
返回{'key':df['key'].unique()[0],'threshold':1,'window':60,'factors':dict(zip(df['category'],df['factors']))
df=df.groupby(['traffic\u group','app\u id','key'])。应用(创建嵌套目录)
下一步是将行组合到每个(流量组、应用程序id)doublet的列表中,并将它们作为dict返回:

df=df.groupby(['traffic\u group','app\u id']).apply(lambda-df:df.tolist())
最后一步是将
df
转换为输出。做这件事有多种方法。一个简单的例子如下:

df=df.reset_index().groupby('traffic_group').apply(lambda df:df.values)
output=dict(zip(df.index,[{app_id:val for u,app_id,val in vals}for vals in df.values]))

使用以下方法:

In [208]: d = {}                                                                                                   

In [209]: grouped = df.groupby(['traffic_group', 'app_id', 'key']).agg(pd.Series.to_dict).to_dict(orient='index')  

In [210]: for t, v in grouped.items(): 
     ...:     traff_gr, app_id, key = t 
     ...:     inner_d = {"key": key, "threshold": 1, "window": 60, 'factors': dict(zip(v['category'].values(), v['f
     ...: actors'].values()))} 
     ...:     d.setdefault(traff_gr, {}).setdefault(app_id, []).append(inner_d) 
     ...:                                                                                                          

In [211]: d                                                                                                        
Out[211]: 
{'desktop': {'app1': [{'key': 'CI',
    'threshold': 1,
    'window': 60,
    'factors': {'html': 16.618628, 'xhr': 35.497082}},
   {'key': 'IP',
    'threshold': 1,
    'window': 60,
    'factors': {'html': 18.294468, 'xhr': 30.422464}}],
  'app2': [{'key': 'CI',
    'threshold': 1,
    'window': 60,
    'factors': {'html': 11.02824, 'json': 33.548279}}]},
 'mobile': {'app1': [{'key': 'IP',
    'threshold': 1,
    'window': 60,
    'factors': {'html': 12.808367, 'image': 14.410632999999999}}]}}

您的解决方案似乎有效,但@Georgios的答案更为“pythonic”,他/她的流程通过解释变得清晰。