2017-08-30 2 views
0

Les enregistrements dans le fichier JSON ressembler à ceci (s'il vous plaît noter ce que « nutriments » ressemble):pandas géants python - TypeError lors de l'analyse JSON: indices de chaîne doivent être des entiers

{ 
"id": 21441, 
"description": "KENTUCKY FRIED CHICKEN, Fried Chicken, EXTRA CRISPY, 
Wing, meat and skin with breading", 
"tags": ["KFC"], 
"manufacturer": "Kentucky Fried Chicken", 
"group": "Fast Foods", 
"portions": [ 
{ 
"amount": 1, 
"unit": "wing, with skin", 
"grams": 68.0 
}, 
... 
], 
"nutrients": [ 
{ 
"value": 20.8, 
"units": "g", 
"description": "Protein", 
"group": "Composition" 
}, 
{'description': 'Total lipid (fat)', 
'group': 'Composition', 
'units': 'g', 
'value': 29.2} 
... 
] 
} 

Voici le code de la exercice de livre *. Il comprend quelques empoignades et assemble les éléments nutritifs pour chaque aliment dans une seule table grande:

import pandas as pd 
import json 

db = pd.read_json("foods-2011-10-03.json") 

nutrients = [] 

for rec in db: 
    fnuts = pd.DataFrame(rec["nutrients"]) 
    fnuts["id"] = rec["id"] 
    nutrients.append(fnuts) 

Cependant, je reçois l'erreur suivante et je ne peux pas comprendre pourquoi:


TypeError         Traceback (most recent call last) 
<ipython-input-23-ac63a09efd73> in <module>() 
     1 for rec in db: 
----> 2  fnuts = pd.DataFrame(rec["nutrients"]) 
     3  fnuts["id"] = rec["id"] 
     4  nutrients.append(fnuts) 
     5 

TypeError: string indices must be integers 

* Ceci est un exemple du livre

+0

Votre JSON n'est pas valide (et même quand on corrige les guillemets et supprime les points, il ne peut pas être chargé par 'pd.read_json'). S'il vous plaît soumettre des données, nous pouvons réellement voir votre problème. – Amadan

+0

@Amadan, voici le lien vers les données: https://github.com/wesm/pydata-book/blob/master/ch07/foods-2011-10-03.json –

Répondre

1

for rec in db effectue l'itération sur noms de colonne. Itérer sur les lignes,

for id, rec in db.iterrows(): 
    fnuts = pd.DataFrame(rec["nutrients"]) 
    fnuts["id"] = rec["id"] 
    nutrients.append(fnuts) 

Ceci est un peu lent cependant (tous les dicts qui ont besoin d'être construits). itertuples est plus rapide; mais puisque vous ne se soucient que deux séries, itérer série est directement sans doute le plus rapide:

for id, value in zip(db['id'], db['nutrients']): 
    fnuts = pd.DataFrame(value) 
    fnuts["id"] = id 
    nutrients.append(fnuts) 
+0

Merci, ça fonctionne bien! Y a-t-il eu des changements dans la façon dont cette itération fonctionne depuis que le livre a été écrit ou doit-il être ajouté à l'errata du livre? –

+0

Désolé, je ne connais pas trop l'histoire des Pandas, et je n'ai pas lu le livre. – Amadan

0

Le code fonctionne parfaitement bien mais le json devrait ressembler à ceci pour que le code fonctionne:

[{ 
"id": 21441, 
"description": "KENTUCKY FRIED CHICKEN, Fried Chicken, EXTRA CRISPY,Wing, meat and skin with breading", 
"tags": ["KFC"], 
"manufacturer": "Kentucky Fried Chicken", 
"group": "Fast Foods", 
"portions": [ 
{"amount": 1, 
"unit": "wing, with skin", 
"grams": 68.0}], 
"nutrients": [{ 
"value": 20.8, 
"units": "g", 
"description": "Protein", 
"group": "Composition" 
}, 
{'description': 'Total lipid (fat)', 
'group': 'Composition', 
'units': 'g', 
'value': 29.2}]}] 

Ceci est un exemple avec un seul enregistrement.

0

Amadan répondu à la question, mais je réussi à le résoudre comme celui-ci avant de voir sa réponse:

for i in range(len(db)): 
    rec = db.loc[i] 
    fnuts = pd.DataFrame(rec["nutrients"]) 
    fnuts["id"] = rec["id"] 
    nutrients.append(fnuts)