将两个关系型pandas数据帧合并为单个嵌套json输出

时间:2018-04-21 08:25:51

标签: python pandas sqlite

我有两个关系数据框,如下面的文件。

df_doc:

|document_id| name|
+-----------+-----+
|          1|  aaa|
|          2|  bbb|

df_topic:

|   topic_id| name|document_id|
+-----------+-----+-----------+
|          1|  xxx|          1|
|          2|  yyy|          2|
|          3|  zzz|          2|

我想将它们合并到一个嵌套的json文件中,如下所述。

[
    {
        "document_id": 1,
        "name": "aaa",
        "topics": [
            {
                "topic_id": 1,
                "name": "xxx"
            }
        ]
    },
    {
        "document_id": 2,
        "name": "bbb",
        "topics": [
            {
                "topic_id": 2,
                "name": "yyy"
            },
            {
                "topic_id": 3,
                "name": "zzz"
            }
        ]
    }
]

也就是说,我希望与pandas.io.json.json_normalize做的相反。

使用sqlite的答案也没关系。

注意: df_doc和df_topic都有“name”列,它们具有相同的名称但值不同

感谢。

1 个答案:

答案 0 :(得分:1)

如果只有2列df_doc使用map首先加入新列title,然后groupby转换为to_dict,然后to_json

s = df_doc.set_index('document_id')['title']
df_topic['title'] = df_topic['document_id'].map(s)

#filter all columns without values in list
cols = df_topic.columns.difference(['document_id','title'])
j = (df_topic.groupby(['document_id','title'])[cols]
             .apply(lambda x: x.to_dict('r'))
             .reset_index(name='topics')
             .to_json(orient='records'))
print (j)

[{"document_id":1,"title":"aaa","topics":[{"name":"xxx","topic_id":1}]},
 {"document_id":2,"title":"bbb","topics":[{"name":"yyy","topic_id":2},
                                          {"name":"zzz","topic_id":3}]}]

如果df_doc中的多列使用join代替map

df = df_topic.merge(df_doc, on='document_id')
print (df)
   topic_id name  document_id title
0         1  xxx            1   aaa
1         2  yyy            2   bbb
2         3  zzz            2   bbb

cols = df.columns.difference(['document_id','title'])
j = (df.groupby(['document_id','title'])[cols]
       .apply(lambda x: x.to_dict('r'))
       .reset_index(name='topics')
       .to_json(orient='records'))

编辑:如果可以使用相同的列名称,请添加参数suffixes,以便将_添加到唯一列和最后strip列的名称:

df = df_topic.merge(df_doc, on='document_id', suffixes=('','_'))
print (df)
   topic_id name  document_id name_
0         1  xxx            1   aaa
1         2  yyy            2   bbb
2         3  zzz            2   bbb

cols = df.columns.difference(['document_id','title'])
j = (df.groupby(['document_id','name_'])[cols]
       .apply(lambda x: x.to_dict('r'))
       .reset_index(name='topics')
       .rename(columns=lambda x: x.rstrip('_'))
       .to_json(orient='records'))
print (j)
[{"document_id":1,"name":"aaa","topics":[{"name":"xxx","name_":"aaa","topic_id":1}]},
 {"document_id":2,"name":"bbb","topics":[{"name":"yyy","name_":"bbb","topic_id":2},
                                         {"name":"zzz","name_":"bbb","topic_id":3}]}]