试着学会像函数式程序员一样思考——我想用我认为是折叠或归约操作来转换数据集。在 R 中,我认为这是一个重塑操作,但我不确定如何翻译这种想法。
我的数据是一个 json 字符串,如下所示:
s =
'[
{"query":"Q1", "detail" : "cool", "rank":1,"url":"awesome1"},
{"query":"Q1", "detail" : "cool", "rank":2,"url":"awesome2"},
{"query":"Q1", "detail" : "cool", "rank":3,"url":"awesome3"},
{"query":"Q#2", "detail" : "same", "rank":1,"url":"newurl1"},
{"query":"Q#2", "detail" : "same", "rank":2,"url":"newurl2"},
{"query":"Q#2", "detail" : "same", "rank":3,"url":"newurl3"}
]'
我想把它变成这样的东西,其中查询是定义“行”的主键,嵌套了与“排名”值和“网址”字段相对应的唯一“行”:
'[
{ "query" : "Q1",
"results" : [
{"rank" : 1, "url": "awesome1"},
{"rank" : 2, "url": "awesome2"},
{"rank" : 3, "url": "awesome3"}
]},
{ "query" : "Q#2",
"results" : [
{"rank" : 1, "url": "newurl1"},
{"rank" : 2, "url": "newurl2"},
{"rank" : 3, "url": "newurl3"},
]}
]'
我知道我可以迭代,但我怀疑有一个功能操作可以进行这种转换,对吧?
也很想知道如何获得更像这样的东西,Version2:
'[
{ "query" : "Q1",
"Common to all results" : [
{"detail" : "cool"}
],
"results" : [
{"rank" : 1, "url": "awesome1"},
{"rank" : 2, "url": "awesome2"},
{"rank" : 3, "url": "awesome3"}
]},
{ "query" : "Q#2",
"Common to all results" : [
{"detail" : "same"}
],
"results" : [
{"rank" : 1, "url": "newurl1"},
{"rank" : 2, "url": "newurl2"},
{"rank" : 3, "url": "newurl3"}
]}
]'
在第二个版本中,我想将所有在同一个查询下重复的数据放入一个“其他东西”容器中,其中“排名”下唯一的所有项目都在“结果”容器中。
我正在处理 mongodb 中的 json 对象,并且可以使用 python 或 javascript 来尝试这种转换。
任何建议,例如此转换的正确名称,可能是在大型数据集上执行此操作的最快方法,都值得赞赏!
编辑
在下面结合@abarnert 的优秀解决方案,试图让我的 Version2 上面的任何其他人处理相同类型的问题,需要在一个级别下分叉一些键,在另一个下分叉其他键......
这是我尝试过的:
from functools import partial
groups = itertools.groupby(initial, operator.itemgetter('query'))
def filterkeys(d,mylist):
return {k: v for k, v in d.items() if k in mylist}
results = ((key, map(partial(filterkeys, mylist=['rank','url']),group)) for key, group in groups)
other_stuff = ((key, map(partial(filterkeys, mylist=['detail']),group)) for key, group in groups)
???
不好了!