[英]How to convert pandas dataframe to uniquely structured nested json
我有一个结构如下的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
}
]
}
}
该结构无疑是令人费解的。
我考虑过以下先前的答案,并试图模仿它们的逻辑无济于事:
任何帮助表示赞赏。 请不仅发布解决方案,还请解释您的逻辑。
我在输入中看不到嵌套字典的任何“阈值”和“窗口”键。 假设它们具有固定值。 根据您的输出,似乎您想为每个三元组(traffic_group,app_id,key)创建(通常)一个不同的嵌套字典。 因此,我们需要使用这三个键进行初始groupby操作。 对于每个组,我们创建嵌套字典:
def create_nested_dicts(df):
return {'key': df['key'].unique()[0], 'threshold': 1, 'window': 60, 'factors': dict(zip(df['category'], df['factors']))}
df = df.groupby(['traffic_group', 'app_id', 'key']).apply(create_nested_dicts)
下一步是将行合并为每个(traffic_group,app_id)双胞胎的列表,并将它们作为字典返回:
df = df.groupby(['traffic_group', 'app_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 _, app_id, val in vals} for vals in df.values]))
好吧,我已经解决了“老式”的问题。 将我的解决方案发布给将来可能需要的任何人。 但是,如果有人能够使用大熊猫做的话,我很乐意看到。
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)
使用以下方法:
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}}]}}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.