【问题标题】:Create dictionary of dictionary from each row and export each row as a json file in python从每一行创建字典字典并将每一行导出为python中的json文件
【发布时间】:2021-11-01 11:32:43
【问题描述】:

我有一个如下所示的 pandas 数据框

我想为每一行创建一个字典,如下所示。字典列表中的特征。

#row1 示例输出。它应该跳过 null 属性 face 和 hat。

{
 "name": "rv",
 "image": "https://img0.png",
 "attributes": [
 { "trait_type": "background", "value":"grey" },
 { "trait_type": "tshirt", "value":"yellow" },
 { "trait_type": "eagle", "value":"male" },
 { "trait_type": "hair", "value":"darktwists" }
]
}

#row3 示例输出。它应该跳过 null 属性 face 和 hair。

{
 "name": "nv",
 "image": "https://img2.png",
 "attributes": [
 { "trait_type": "background", "value":"brown" },
 { "trait_type": "tshirt", "value":"americanflag" },
 { "trait_type": "eagle", "value":"male" },
 { "trait_type": "hat", "value":"policehat" }
]
}

像这样,每行输出都应该存储在一个单独的 JSON 文件中。

我使用 lambda apply 和 _to_json 进行了尝试,但遇到了两个问题: 1)无法以所需格式将属性打包为字典内的单独字典。 2)JSON将HTTPS图像链接中的正斜杠“//”存储为“/”

非常感谢任何帮助。谢谢。

【问题讨论】:

    标签: python json pandas dictionary reshape


    【解决方案1】:

    首先,您需要融合 df 以将其构造为字典中的 "attribute" 键并相应地重命名列:

    df = df.melt(id_vars=['name','image'])
    df = df.rename(columns={'variable':"trait_type"})
    

    然后我们需要根据名称和图像(以及您希望包含在 json 结构中的其他唯一值)对它们进行分组。然后迭代组并构造字典结构:

    results = []
    for index, group in df.groupby(['name','image']):
        temp_dict = {}
        temp_dict["name"] = index[0]
        temp_dict["image"] = index[1]
        temp_dict["attributes"] = group[["trait_type","value"]].to_dict("records")
        results.append(temp_dict)
    

    这应该会给你你喜欢的结果。

    简洁答案(Timus 建议):

    您可以在一行中执行整个操作:

    dicts = (df.melt(id_vars=['name', 'image'], var_name='trait_type')
        .dropna()
        .groupby(['name', 'image'])[['trait_type', 'value']]
        .apply(pd.DataFrame.to_dict, orient='records')
        .reset_index(drop=False)
        .rename(columns={0: 'attributes'})
        .to_dict(orient='records'))
    

    【讨论】:

    • id_vars=['kunta','date_q'] 你可能是指id_vars=['name','image']?并且:您不需要df.rename(..),只需在melt 中使用kwarg var_name='trait_type'
    • 最后一句话(对不起!):你可以非常巧妙地链接整个操作(链接是 Pandas 的方式):dicts = (df.melt(id_vars=['name', 'image'], var_name='trait_type').dropna().groupby(['name', 'image'])[['trait_type', 'value']].apply(pd.DataFrame.to_dict, orient='records').reset_index(drop=False).rename(columns={0: 'attributes'}).to_dict(orient='records')).
    • 感谢您的精彩评论@Timus!我正在玩自己的 df 来测试代码。我会按照您的建议更新答案:D
    【解决方案2】:

    第一件事:你的JSON格式不是通用类型格式,所以不能直接使用数据帧的pandas to_json()和/或to_dict()方法创建,所以需要手动处理

    第二件事:pandas 默认添加转义字符,这就是为什么 'https://img0.png'https:\\/\\/img0.png 替换

    out=(df.assign(attributes=df[['background',  'tshirt', 'eagle', 'face', 'hat']]
                            .apply(lambda x:[{'trait_type':index, 'value':value}
                                             for index, value in x[x.notna()].iteritems()],
                                   axis=1))
                            [['name', 'image', 'attributes']]
                            .apply(dict, axis=1)
                            .tolist()
         )
    

    输出:

    [
        {
            'name': 'rv', 
            'image': 'https://img0.png', 
            'attributes': [
                    {'trait_type': 'background', 'value': 'gray'}, 
                    {'trait_type': 'tshirt', 'value': 'yellow'}, 
                    {'trait_type': 'eagle', 'value': 'male'}
                    ]
        }, 
        {
            'name': 'cv', 
            'image': 'https://img1.png', 
            'attributes': [
                    {'trait_type': 'background', 'value': 'yellow'}, 
                    {'trait_type': 'tshirt', 'value': 'green'}, 
                    {'trait_type': 'eagle', 'value': 'male'}
                    ]
        }
    ]
    

    在此之后,您将在变量 out 中获得一个字典列表,您可以将其传递给 json.dumps 以从中创建 json,如下所示:

    >>> import json
    >>> print(json.dumps(out, indent=4)
    [
        {
            "name": "rv",
            "image": "https://img0.png",
            "attributes": [
                {
                    "trait_type": "background",
                    "value": "gray"
                },
                {
                    "trait_type": "tshirt",
                    "value": "yellow"
                },
                {
                    "trait_type": "eagle",
                    "value": "male"
                }
            ]
        },
        {
            "name": "cv",
            "image": "https://img1.png",
            "attributes": [
                {
                    "trait_type": "background",
                    "value": "yellow"
                },
                {
                    "trait_type": "tshirt",
                    "value": "green"
                },
                {
                    "trait_type": "eagle",
                    "value": "male"
                }
            ]
        }
    ]
    

    【讨论】:

    • 感谢您的解释和回答。正是我需要的:)
    • 如何将“out”中的每个列表值导出到单独的 JSON 文件中?
    • 您将拥有一个列表out中的整个字典列表,您只需要迭代列表中的项目,并将其作为json写入相应的文件,例如:for d in out: json.dumps(d, fi)其中fi 表示使用例如f1 = open('file1.txt', 'w') 创建的每个文件的文件缓冲区
    • 谢谢。如果您可以将那篇文章添加到您的主要回复中,这对其他人也有帮助:)
    猜你喜欢
    • 2016-06-07
    • 2016-03-09
    • 1970-01-01
    • 2018-11-01
    • 2016-03-07
    • 1970-01-01
    • 2018-06-02
    • 2018-07-21
    • 2021-06-20
    相关资源
    最近更新 更多