0

我有一个 JSON 对象,我正在尝试对其进行改装以进行不同的分析,并且我正在寻找一种功能转换来基于两个唯一键控字段聚合一个字段。

我的数据集如下所示:

myjson = 

[
{
"name": "Fred",
"class": "Algebra",
"topic" : "polynomials",
"extra" : "True"
},
{
"name": "Fred",
"class": "Algebra",
"topic" : "polynomial division",
"extra" : "False"
},
{
"name": "Fred",
"class": "Algebra",
"topic" : "solving",
"extra" : "True"
},
{
"name": "Willbert",
"class": "Dance",
"topic" : "Fancy",
"extra" : "False"
},
{
"name": "Willbert",
"class": "Dance",
"topic" : "Country",
"extra" : "True"
}
]

我想使用 Name 和 Class 作为聚合主题字段的唯一键——“额外”字段的内容不同,我希望它们都保持与第一个条目相关联的数据——即也就是说,它们不需要合并,而应该只从一条记录中获取值。

所以,我想把上面的变成:

[
{
"name": "Fred",
"class": "Algebra",
"topic" : ["polynomials","polynomial division","solving"],
"extra" : "True"
},
{
"name": "Willbert",
"class": "Dance",
"topic" : ["Fancy","Country"],
"extra" : "False"
}
]

甚至将主题连接在一起,作为一个字符串:

[
{
"name": "Fred",
"class": "Algebra",
"topic" : "polynomials polynomial division solving"
},
{
"name": "Willbert",
"class": "Dance",
"topic" : "Fancy Country"
}
]

在使用 groupby 解决之前,我曾经遇到过类似的问题,但是对于如何开始这个问题有点不知所措,特别是因为我现在有两个键控条目,而不仅仅是一个。

更新

我可以得到一把钥匙让我开始,这在这个例子中有效......

groups = itertools.groupby(myjson,lambda x: (x['name']))
[(k,list(g)) for k,g in groups]

但在我的实际数据集中,仅“名称”不足以消除歧义——我需要按“名称”和“类别”进行分组。

这不起作用:

groups = itertools.groupby(myjson,lambda x: (x['name'],x['class']))
[(k,list(g)) for k,g in groups]

更新 2

发现这个链接解决了一个类似的问题,这表明在 2 个组上的键控不是微不足道的——这真的有必要吗,或者是否有另一种对 itertools 的来龙去脉更有经验的人可以指出更好地使用 groupby 的方法?

4

1 回答 1

1

您可以使用字典按某个键进行分组:

data = {}
key = operator.itemgetter("name", "class")
for record in myjson:
    k = key(record)
    if k in data:
        data[k]["topic"].append(record["topic"])
    else:
        data[k] = record.copy()
        data[k]["topic"] = [record["topic"]]
result = data.values()

循环将输入列表转换为由所需键键入的字典,累积"topic"字段。由于我们在值中包含键,我们可以简单地提取值以获得所需的结果。

于 2013-07-24T20:00:58.137 回答