部分展平存储在 df 列中的嵌套 JSON 个对象

Partly flatten nested JSON objects stored in df column

我有一个包含 3 列的数据框 (INSTNR, Enhedsadresser, API_response),其中第 3 列 (API_response) 包含 JSON 个对象。我想展平 JSON 对象并将提取的信息存储在同一个 df 中的不同列中。我对提取 kategoriresultater -> addresse -> idresultater -> adresse -> adgangsadresseid资料。

我试过:

data = json_normalize(data=df['API_response'], record_path='resultater',
                            meta=['kategori'], errors='ignore')

但它只是 returns TypeError: string indices must be integers

data = json_normalize(data=df['API_response']) 给了我一个包含索引列表的专栏...

如何提取所需的信息?

JSON 对象的示例:

{
  "kategori": "A",
  "resultater": [
    {
      "adresse": {
        "id": "0a3f50bc-f815-32b8-e044-0003ba298018",
        "vejnavn": "Staldgaardsgade",
        "adresseringsvejnavn": "Staldgaardsgade",
        "husnr": "39A",
        "supplerendebynavn": null,
        "postnr": "7100",
        "postnrnavn": "Vejle",
        "status": 1,
        "virkningstart": "2009-11-24T02:15:25.000Z",
        "virkningslut": null,
        "adgangsadresseid": "0a3f5090-edef-32b8-e044-0003ba298018",
        "etage": "st",
        "dør": "th",
        "href": "https://api.dataforsyningen.dk/adresser/0a3f50bc-f815-32b8-e044-0003ba298018"
      },
      "aktueladresse": {
        "id": "0a3f50bc-f815-32b8-e044-0003ba298018",
        "vejnavn": "Staldgaardsgade",
        "adresseringsvejnavn": "Staldgaardsgade",
        "husnr": "39A",
        "supplerendebynavn": null,
        "postnr": "7100",
        "postnrnavn": "Vejle",
        "status": 1,
        "virkningstart": "2009-11-24T02:15:25.000Z",
        "virkningslut": null,
        "adgangsadresseid": "0a3f5090-edef-32b8-e044-0003ba298018",
        "etage": "st",
        "dør": "th",
        "href": "https://api.dataforsyningen.dk/adresser/0a3f50bc-f815-32b8-e044-0003ba298018"
      },
      "vaskeresultat": {
        "variant": {
          "vejnavn": "Staldgaardsgade",
          "husnr": "39A",
          "etage": "st",
          "dør": "th",
          "supplerendebynavn": null,
          "postnr": "7100",
          "postnrnavn": "Vejle"
        },
        "afstand": 0,
        "forskelle": {
          "vejnavn": 0,
          "husnr": 0,
          "postnr": 0,
          "postnrnavn": 0,
          "etage": 0,
          "dør": 0
        },
        "parsetadresse": {
          "vejnavn": "Staldgaardsgade",
          "husnr": "39A",
          "etage": "st",
          "dør": "th",
          "postnr": "7100",
          "postnrnavn": "Vejle"
        },
        "ukendtetokens": [],
        "anvendtstormodtagerpostnummer": null
      }
    }
  ]
}

Link 到 API 包含此 JSON 对象的响应:https://api.dataforsyningen.dk/datavask/adresser?betegnelse=Staldgaardsgade%2039A%20st%20th,%207100%20Vejle

编辑 1

我用数据和 python 脚本创建了 GitHub 回购:https://github.com/mantasbacys/TREFOR

Series.str.get 可以帮助您从字典列中提取单个元素。

如果 API_response 是一列格式为您的示例的字典,您可以使用:

df['kategori'] = df['api_response'].str.get('kategori')
df['id'] = (
    df['api_response']
    .str.get('resultater')  # get resultater object
    .str.get(0)  # get first element in list
    .str.get('adresse')
    .str.get('id')
)
df['adgangsadresseid'] =  = (
    df['api_response']
    .str.get('resultater')  # get resultater object
    .str.get(0)  # get first element in list
    .str.get('adresse')
    .str.get('adgangsadresseid')
)

请注意,如果格式不匹配,这将失败,因此请仔细检查!例如。如果 resultater 列表中有多个元素,您可能需要使用 Series.explode 代替。


编辑:

您的文件显示 API_response 列实际上包含已解析的 JSON 字典,保存为 字符串 。这意味着 .str.get 方法不起作用,因为这些值不是有效的字典。

作为快速修复,您应该先将字典字符串转换为实际字典:

def convert(s): 
    """Convert dictionary string to JSON-like format and parse with json module"""
    s = s.replace("'", '"')
    s = s.replace("None", "null")
    return json.loads(s)

df['api_response'] = df.API_response.apply(convert)
# Alternative - UNSAFE! (see 
# df['api_response'] = df.API_response.apply(eval)

我假设发生这种情况是因为您首先下载数据,然后将其解析为字典,并在再次加载之前保存在文件中。保存文件时会发生这种到字符串列的转换。

为避免这种与字符串的转换来回转换,请尝试在单个脚本中解析 JSON 并提取感兴趣的值。