部分展平存储在 df 列中的嵌套 JSON 个对象
Partly flatten nested JSON objects stored in df column
我有一个包含 3 列的数据框 (INSTNR, Enhedsadresser, API_response),其中第 3 列 (API_response) 包含 JSON 个对象。我想展平 JSON 对象并将提取的信息存储在同一个 df 中的不同列中。我对提取 kategori、resultater -> addresse -> id 和 resultater -> 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 并提取感兴趣的值。
我有一个包含 3 列的数据框 (INSTNR, Enhedsadresser, API_response),其中第 3 列 (API_response) 包含 JSON 个对象。我想展平 JSON 对象并将提取的信息存储在同一个 df 中的不同列中。我对提取 kategori、resultater -> addresse -> id 和 resultater -> 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 并提取感兴趣的值。