web-dev-qa-db-fra.com

Pandas dataframe à un JSON imbriqué dynamique

Je veux créer mon dataframe qui ressemble à ceci:

    employeeId  firstName   lastName    emailAddress    isDependent employeeIdTypeCode  entityCode  sourceCode  roleCode
0   E123456 Andrew  Hoover  [email protected] False   001 AE  AHR EMPLR
0   102939485   Andrew  Hoover  [email protected] False   002 AE  AHR EMPLR
2   E123458 Celeste Riddick [email protected]    True    001 AE  AHR EMPLR
2   354852739   Celeste Riddick [email protected]    True    002 AE  AHR EMPLR
1   E123457 Curt    Austin  [email protected]    True    001 AE  AHR EMPLR
1   675849302   Curt    Austin  [email protected]    True    002 AE  AHR EMPLR
3   E123459 Hazel   Tooley  [email protected] False   001 AE  AHR EMPLR
3   937463528   Hazel   Tooley  [email protected] False   002 AE  AHR EMPLR

Et pour chaque ligne, je souhaite le convertir au format JSON imbriqué ... Je souhaite donc que mon code JSON ressemble à ceci pour chaque individu, car je souhaite parcourir le cadre de données et le publier sur une API. 

{  
   "individualInfo":  
      {  
         "individualIdentifier":[  
            {  
               "identityTypeCode":"001",
               "identifierValue":"E123456",
               "profileInfo":{  
                  "firstName":"Andrew",
                  "lastName":"Hoover",
                  "emailAddress":"[email protected]"
               }
            },
            {  
               "identityTypeCode":"002",
               "identifierValue":"102939485",
               "profileInfo":{  
                   "firstName":"Andrew",
                  "lastName":"Hoover",
                  "emailAddress":"[email protected]"
               }
            }
         ],
         "entityCode":"AE",
         "sourceCode":"AHR",
         "roleCode":"EMPLR"
         "isDependent":False
      }
} 

La chose importante ici est que je veux que mon JSON soit généré de manière agnostique à partir des colonnes Id arrivant sur le cadre de données. Ainsi, s'il y a, par exemple, un autre ID sur le cadre de données, je souhaite que cet ID ait un autre objet de dictionnaire avec les mêmes informations de profil. Ainsi, chaque profil peut avoir un nombre quelconque de Id avec lui.

Code que je pourrais faire:

j = (result.groupby(['identifierValue','identityTypeCode'], as_index=False).apply(lambda x: x[['firstName','lastName','emailAddress']].to_dict('r')).reset_index().rename(columns={0:'ProfileInfo'}).to_json(orient='records'))

Serait-il possible de réaliser ce genre de chose dynmiquement dans des pandas? Merci beaucoup pour l'aide!

Peu d'autres questions que je pourrais trouver pour nidifier:

Convertissez Pandas Dataframe en JSON imbriqué

pandas groupby à imbriqué json

Aucune de ces questions ne m'aide, car je souhaite que chaque index de mon cadre de données soit converti en une charge JSON individuelle, car chaque individu se rend sur un service API que j'ai pour poster les données dans la base de données. 

5
Manas Jani

Il semble que le moyen le plus sensé de retirer ceci est:

info_dict = df.set_index(['identifierValue', 'identifierValue']).to_dict('index')

Ensuite, chaque fois que vous obtenez profileInfo dans votre JSON, vous pouvez référencer le info_dict ci-dessus avec la paire de clés appropriée ('identifierValue', 'identifierValue')

Je ne comprends pas quelle est la mise en forme souhaitée, mais c'est un début.

5
Brian Joseph

Ce n'est pas vraiment une solution Pandas mais ça marche:

Commence à partir de votre result dataframe

from collections import defaultdict
import json

result = 'your data frame'

dicted = defaultdict(dict)
for r in result.values.tolist():
    identifierValue, firstName, lastName, emailAddress,isDependent,\
    identityTypeCode, entityCode, sourceCode,roleCode = r
    tupled_criteria = (firstName,lastName,emailAddress)
    if dicted[tupled_criteria].get("individualInfo"):
        pass
    else:
        dicted[tupled_criteria]["individualInfo"] = {}

    dicted[tupled_criteria]["individualInfo"]['entityCode'] = entityCode
    dicted[tupled_criteria]["individualInfo"]['soruceCode'] = sourceCode
    dicted[tupled_criteria]["individualInfo"]['roleCode'] = roleCode
    dicted[tupled_criteria]["individualInfo"]['isDependent'] = isDependent
    if dicted[tupled_criteria]["individualInfo"].get("individualIdentifier"):
        pass
    else:
        dicted[tupled_criteria]["individualInfo"]["individualIdentifier"] = []
    dicted[tupled_criteria]["individualInfo"]["individualIdentifier"]\
        .append({"identityTypeCode":identityTypeCode,
                   "identifierValue":identifierValue,
                    "profileInfo":{  
                      "firstName":firstName,
                      "lastName":lastName,
                      "emailAddress":emailAddress}})

for k,v in dicted.items():
    print(k,'\n',json.dumps(v),'\n\n')
1
fcsr

Peut-être pouvez-vous parcourir un groupe, puis effectuer une autre itération pour chaque ligne de ce groupe. Ainsi, en créant une structure de dictionnaire imbriquée:

Ceci explique une façon de procéder:

import pandas as pd
df = pd.DataFrame({"entityCode":[1,1,3,3],"sourceCode":[4,4,6,6],'identityTypeCode':[7,8,9,10]})
results = []
for i, sub_df in df.groupby(["entityCode","sourceCode"]):
    entityCode, sourceCode = i
    d = {}
    d["individualInfo"] = {"entityCode":entityCode, "sourceCode":sourceCode}
    sub_result = []
    for _, row in sub_df[["identityTypeCode"]].drop_duplicates().iterrows():
        sub_result.append(row.to_dict())
    d["individualIdentifier"] = sub_result
    results.append(d)
results

qui retourne quelque chose comme ceci:

[{'individualInfo': {'entityCode': 1, 'sourceCode': 4},
  'individualIdentifier': [{'identityTypeCode': 7}, {'identityTypeCode': 8}]},
 {'individualInfo': {'entityCode': 3, 'sourceCode': 6},
  'individualIdentifier': [{'identityTypeCode': 9}, {'identityTypeCode': 10}]}]

ensuite, vous pouvez convertir le dictionnaire en json.

0
erncyp